class AboutController < ApplicationController
layout 'public'
+ before_action :require_open_federation!, only: [:show, :more]
before_action :set_body_classes, only: :show
before_action :set_instance_presenter
before_action :set_expires_in
private
+ def require_open_federation!
+ not_found if whitelist_mode?
+ end
+
def new_user
User.new.tap do |user|
user.build_account
# frozen_string_literal: true
class ActivityPub::BaseController < Api::BaseController
+ skip_before_action :require_authenticated_user!
+
private
def set_cache_headers
# frozen_string_literal: true
-class ActivityPub::InboxesController < Api::BaseController
+class ActivityPub::InboxesController < ActivityPub::BaseController
include SignatureVerification
include JsonLdHelper
include AccountOwnedConcern
--- /dev/null
+# frozen_string_literal: true
+
+class Admin::DomainAllowsController < Admin::BaseController
+ before_action :set_domain_allow, only: [:destroy]
+
+ def new
+ authorize :domain_allow, :create?
+
+ @domain_allow = DomainAllow.new(domain: params[:_domain])
+ end
+
+ def create
+ authorize :domain_allow, :create?
+
+ @domain_allow = DomainAllow.new(resource_params)
+
+ if @domain_allow.save
+ log_action :create, @domain_allow
+ redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.created_msg')
+ else
+ render :new
+ end
+ end
+
+ def destroy
+ authorize @domain_allow, :destroy?
+ UnallowDomainService.new.call(@domain_allow)
+ redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
+ end
+
+ private
+
+ def set_domain_allow
+ @domain_allow = DomainAllow.find(params[:id])
+ end
+
+ def resource_params
+ params.require(:domain_allow).permit(:domain)
+ end
+end
module Admin
class InstancesController < BaseController
+ before_action :set_domain_block, only: :show
+ before_action :set_domain_allow, only: :show
+ before_action :set_instance, only: :show
+
def index
authorize :instance, :index?
def show
authorize :instance, :show?
- @instance = Instance.new(Account.by_domain_accounts.find_by(domain: params[:id]) || DomainBlock.find_by!(domain: params[:id]))
@following_count = Follow.where(account: Account.where(domain: params[:id])).count
@followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count
@reports_count = Report.where(target_account: Account.where(domain: params[:id])).count
@blocks_count = Block.where(target_account: Account.where(domain: params[:id])).count
@available = DeliveryFailureTracker.available?(Account.select(:shared_inbox_url).where(domain: params[:id]).first&.shared_inbox_url)
@media_storage = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size)
- @domain_block = DomainBlock.rule_for(params[:id])
end
private
+ def set_domain_block
+ @domain_block = DomainBlock.rule_for(params[:id])
+ end
+
+ def set_domain_allow
+ @domain_allow = DomainAllow.rule_for(params[:id])
+ end
+
+ def set_instance
+ resource = Account.by_domain_accounts.find_by(domain: params[:id])
+ resource ||= @domain_block
+ resource ||= @domain_allow
+
+ if resource
+ @instance = Instance.new(resource)
+ else
+ not_found
+ end
+ end
+
def filtered_instances
- InstanceFilter.new(filter_params).results
+ InstanceFilter.new(whitelist_mode? ? { allowed: true } : filter_params).results
end
def paginated_instances
skip_before_action :store_current_location
skip_before_action :require_functional!
+ before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access?
before_action :set_cache_headers
protect_from_forgery with: :null_session
nil
end
+ def require_authenticated_user!
+ render json: { error: 'This API requires an authenticated user' }, status: 401 unless current_user
+ end
+
def require_user!
if !current_user
render json: { error: 'This method requires an authenticated user' }, status: 422
def set_cache_headers
response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
end
+
+ def disallow_unauthenticated_api_access?
+ authorized_fetch_mode?
+ end
end
before_action :check_account_suspension, only: [:show]
before_action :check_enabled_registrations, only: [:create]
+ skip_before_action :require_authenticated_user!, only: :create
+
respond_to :json
def show
# frozen_string_literal: true
class Api::V1::AppsController < Api::BaseController
+ skip_before_action :require_authenticated_user!
+
def create
@app = Doorkeeper::Application.create!(application_options)
render json: @app, serializer: REST::ApplicationSerializer
class Api::V1::Instances::ActivityController < Api::BaseController
before_action :require_enabled_api!
+
skip_before_action :set_cache_headers
respond_to :json
end
def require_enabled_api!
- head 404 unless Setting.activity_api_enabled
+ head 404 unless Setting.activity_api_enabled && !whitelist_mode?
end
end
class Api::V1::Instances::PeersController < Api::BaseController
before_action :require_enabled_api!
+
skip_before_action :set_cache_headers
respond_to :json
private
def require_enabled_api!
- head 404 unless Setting.peers_api_enabled
+ head 404 unless Setting.peers_api_enabled && !whitelist_mode?
end
end
class Api::V1::InstancesController < Api::BaseController
respond_to :json
+
skip_before_action :set_cache_headers
def show
include UserTrackingConcern
include SessionTrackingConcern
include CacheConcern
+ include DomainControlHelper
helper_method :current_account
helper_method :current_session
helper_method :current_theme
helper_method :single_user_mode?
helper_method :use_seamless_external_login?
+ helper_method :whitelist_mode?
rescue_from ActionController::RoutingError, with: :not_found
rescue_from ActiveRecord::RecordNotFound, with: :not_found
end
def authorized_fetch_mode?
- ENV['AUTHORIZED_FETCH'] == 'true'
+ ENV['AUTHORIZED_FETCH'] == 'true' || Rails.configuration.x.whitelist_mode
end
def public_fetch_mode?
extend ActiveSupport::Concern
included do
+ before_action :authenticate_user!, if: -> { whitelist_mode? && request.format != :json }
before_action :set_account, if: :account_required?
before_action :check_account_approval, if: :account_required?
before_action :check_account_suspension, if: :account_required?
class DirectoriesController < ApplicationController
layout 'public'
- before_action :check_enabled
+ before_action :authenticate_user!, if: :whitelist_mode?
+ before_action :require_enabled!
before_action :set_instance_presenter
before_action :set_tag, only: :show
before_action :set_tags
private
- def check_enabled
+ def require_enabled!
return not_found unless Setting.profile_directory
end
end
def default_redirect_path
- if request.path.start_with?('/web')
+ if request.path.start_with?('/web') || whitelist_mode?
new_user_session_path
elsif single_user_mode?
short_account_path(Account.local.without_suspended.where('id > 0').first)
skip_before_action :store_current_location
+ before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_media_attachment
before_action :verify_permitted_status!
before_action :check_playable, only: :player
skip_before_action :store_current_location
+ before_action :authenticate_user!, if: :whitelist_mode?
+
def show
RedisLock.acquire(lock_options) do |lock|
if lock.acquired?
class PublicTimelinesController < ApplicationController
layout 'public'
- before_action :check_enabled
+ before_action :authenticate_user!, if: :whitelist_mode?
+ before_action :require_enabled!
before_action :set_body_classes
before_action :set_instance_presenter
private
- def check_enabled
+ def require_enabled!
not_found unless Setting.timeline_preview
end
layout 'modal'
+ before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_interaction_type
before_action :set_status
before_action :set_body_classes
layout 'public'
before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
+ before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_tag
before_action :set_body_classes
before_action :set_instance_presenter
end
end
- DomainBlock.blocked?(domain)
+ if whitelist_mode?
+ !DomainAllow.allowed?(domain)
+ else
+ DomainBlock.blocked?(domain)
+ end
+ end
+
+ def whitelist_mode?
+ Rails.configuration.x.whitelist_mode
end
end
--- /dev/null
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: domain_allows
+#
+# id :bigint(8) not null, primary key
+# domain :string default(""), not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class DomainAllow < ApplicationRecord
+ include DomainNormalizable
+
+ validates :domain, presence: true, uniqueness: true
+
+ scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
+
+ class << self
+ def allowed?(domain)
+ !rule_for(domain).nil?
+ end
+
+ def rule_for(domain)
+ return if domain.blank?
+
+ uri = Addressable::URI.new.tap { |u| u.host = domain.gsub(/[\/]/, '') }
+
+ find_by(domain: uri.normalized_host)
+ end
+ end
+end
def initialize(resource)
@domain = resource.domain
- @accounts_count = resource.is_a?(DomainBlock) ? nil : resource.accounts_count
+ @accounts_count = resource.respond_to?(:accounts_count) ? resource.accounts_count : nil
@domain_block = resource.is_a?(DomainBlock) ? resource : DomainBlock.rule_for(domain)
+ @domain_allow = resource.is_a?(DomainAllow) ? resource : DomainAllow.rule_for(domain)
end
def countable?
scope = DomainBlock
scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?
scope.order(id: :desc)
+ elsif params[:allowed].present?
+ scope = DomainAllow
+ scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?
+ scope.order(id: :desc)
else
scope = Account.remote
scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?
--- /dev/null
+# frozen_string_literal: true
+
+class DomainAllowPolicy < ApplicationPolicy
+ def create?
+ admin?
+ end
+
+ def destroy?
+ admin?
+ end
+end
end
def signing_enabled?
- ENV['AUTHORIZED_FETCH'] != 'true'
+ ENV['AUTHORIZED_FETCH'] != 'true' && !Rails.configuration.x.whitelist_mode
end
end
--- /dev/null
+# frozen_string_literal: true
+
+class UnallowDomainService < BaseService
+ def call(domain_allow)
+ Account.where(domain: domain_allow.domain).find_each do |account|
+ SuspendAccountService.new.call(account, destroy: true)
+ end
+
+ domain_allow.destroy
+ end
+end
--- /dev/null
+- content_for :header_tags do
+ = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+
+- content_for :page_title do
+ = t('admin.domain_allows.add_new')
+
+= simple_form_for @domain_allow, url: admin_domain_allows_path do |f|
+ = render 'shared/error_messages', object: @domain_allow
+
+ .fields-group
+ = f.input :domain, wrapper: :with_label, label: t('admin.domain_blocks.domain'), required: true
+
+ .actions
+ = f.button :button, t('admin.domain_allows.add_new'), type: :submit
%strong= t('admin.instances.moderation.title')
%ul
%li= filter_link_to t('admin.instances.moderation.all'), limited: nil
- %li= filter_link_to t('admin.instances.moderation.limited'), limited: '1'
+
+ - unless whitelist_mode?
+ %li= filter_link_to t('admin.instances.moderation.limited'), limited: '1'
%div{ style: 'flex: 1 1 auto; text-align: right' }
- = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path, class: 'button'
+ - if whitelist_mode?
+ = link_to t('admin.domain_allows.add_new'), new_admin_domain_allow_path, class: 'button'
+ - else
+ = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path, class: 'button'
-= form_tag admin_instances_url, method: 'GET', class: 'simple_form' do
- .fields-group
- - Admin::FilterHelper::INSTANCES_FILTERS.each do |key|
- - if params[key].present?
- = hidden_field_tag key, params[key]
+- unless whitelist_mode?
+ = form_tag admin_instances_url, method: 'GET', class: 'simple_form' do
+ .fields-group
+ - Admin::FilterHelper::INSTANCES_FILTERS.each do |key|
+ - if params[key].present?
+ = hidden_field_tag key, params[key]
- - %i(by_domain).each do |key|
- .input.string.optional
- = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.instances.#{key}")
+ - %i(by_domain).each do |key|
+ .input.string.optional
+ = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.instances.#{key}")
- .actions
- %button= t('admin.accounts.search')
- = link_to t('admin.accounts.reset'), admin_instances_path, class: 'button negative'
+ .actions
+ %button= t('admin.accounts.search')
+ = link_to t('admin.accounts.reset'), admin_instances_path, class: 'button negative'
%hr.spacer/
- unless first_item
•
= t('admin.domain_blocks.rejecting_reports')
+ - elsif whitelist_mode?
+ = t('admin.accounts.whitelisted')
- else
= t('admin.accounts.no_limits_imposed')
- if instance.countable?
.trends__item__current{ title: t('admin.instances.known_accounts', count: instance.accounts_count) }= number_to_human instance.accounts_count, strip_insignificant_zeros: true
+
= paginate paginated_instances
= link_to t('admin.accounts.title'), admin_accounts_path(remote: '1', by_domain: @instance.domain), class: 'button'
%div{ style: 'float: right' }
- - if @domain_block
+ - if @domain_allow
+ = link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
+ - elsif @domain_block
= link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@domain_block), class: 'button'
- else
= link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'
%hr.spacer/
- .fields-group
- = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html')
+ - unless whitelist_mode?
+ .fields-group
+ = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html')
- .fields-group
- = f.input :show_known_fediverse_at_about_page, as: :boolean, wrapper: :with_label, label: t('admin.settings.show_known_fediverse_at_about_page.title'), hint: t('admin.settings.show_known_fediverse_at_about_page.desc_html')
+ .fields-group
+ = f.input :show_known_fediverse_at_about_page, as: :boolean, wrapper: :with_label, label: t('admin.settings.show_known_fediverse_at_about_page.title'), hint: t('admin.settings.show_known_fediverse_at_about_page.desc_html')
.fields-group
= f.input :show_staff_badge, as: :boolean, wrapper: :with_label, label: t('admin.settings.show_staff_badge.title'), hint: t('admin.settings.show_staff_badge.desc_html')
.fields-group
= f.input :open_deletion, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.deletion.title'), hint: t('admin.settings.registrations.deletion.desc_html')
- .fields-group
- = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html')
+ - unless whitelist_mode?
+ .fields-group
+ = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html')
- .fields-group
- = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html')
+ .fields-group
+ = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html')
- .fields-group
- = f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
+ .fields-group
+ = f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
- .fields-group
- = f.input :profile_directory, as: :boolean, wrapper: :with_label, label: t('admin.settings.profile_directory.title'), hint: t('admin.settings.profile_directory.desc_html')
+ .fields-group
+ = f.input :profile_directory, as: :boolean, wrapper: :with_label, label: t('admin.settings.profile_directory.title'), hint: t('admin.settings.profile_directory.desc_html')
.fields-group
= f.input :spam_check_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.spam_check_enabled.title'), hint: t('admin.settings.spam_check_enabled.desc_html')
.fields-group
= f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
- = 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_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 } unless whitelist_mode?
= 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 }
= f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html')
= f.input :invite_code, as: :hidden
.fields-group
- = f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path)
+ = f.input :agreement, as: :boolean, wrapper: :with_label, label: whitelist_mode? ? t('auth.checkbox_agreement_without_rules_html', terms_path: terms_path) : t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path)
.actions
= f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit
= link_to root_url, class: 'brand' do
= svg_logo_full
- = link_to t('directories.directory'), explore_path, class: 'nav-link optional' if Setting.profile_directory
- = link_to t('about.about_this'), about_more_path, class: 'nav-link optional'
- = link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link optional'
+ - unless whitelist_mode?
+ = link_to t('directories.directory'), explore_path, class: 'nav-link optional' if Setting.profile_directory
+ = link_to t('about.about_this'), about_more_path, class: 'nav-link optional'
+ = link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link optional'
+
.nav-center
+
.nav-right
- if user_signed_in?
= link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn'
--- /dev/null
+# frozen_string_literal: true
+
+Rails.application.configure do
+ config.x.whitelist_mode = ENV['WHITELIST_MODE'] == 'true'
+end
username: Username
warn: Warn
web: Web
+ whitelisted: Whitelisted
action_logs:
actions:
assigned_to_self_report: "%{name} assigned report %{target} to themselves"
week_interactions: interactions this week
week_users_active: active this week
week_users_new: users this week
+ domain_allows:
+ add_new: Whitelist domain
+ created_msg: Domain has been successfully whitelisted
+ destroyed_msg: Domain has been removed from the whitelist
+ undo: Remove from whitelist
domain_blocks:
add_new: Add new domain block
created_msg: Domain block is now being processed
apply_for_account: Request an invite
change_password: Password
checkbox_agreement_html: I agree to the <a href="%{rules_path}" target="_blank">server rules</a> and <a href="%{terms_path}" target="_blank">terms of service</a>
+ checkbox_agreement_without_rules_html: I agree to the <a href="%{terms_path}" target="_blank">terms of service</a>
delete_account: Delete account
delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.
didnt_get_confirmation: Didn't receive confirmation instructions?
setting_use_pending_items: Hide timeline updates behind a click instead of automatically scrolling the feed
username: Your username will be unique on %{domain}
whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word
+ domain_allow:
+ domain: This domain will be able to fetch data from this server and incoming data from it will be processed and stored
featured_tag:
name: 'You might want to use one of these:'
imports:
s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_url, highlights_on: %r{/admin/accounts|/admin/pending_accounts}
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path
s.item :tags, safe_join([fa_icon('tag fw'), t('admin.tags.title')]), admin_tags_path
- s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url(limited: '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks}, if: -> { current_user.admin? }
+ s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url(limited: whitelist_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.admin? }
s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.admin? }
end
namespace :admin do
get '/dashboard', to: 'dashboard#index'
+ resources :domain_allows, only: [:new, :create, :show, :destroy]
resources :domain_blocks, only: [:new, :create, :show, :destroy]
resources :email_domain_blocks, only: [:index, :new, :create, :destroy]
resources :action_logs, only: [:index]
--- /dev/null
+class CreateDomainAllows < ActiveRecord::Migration[5.2]
+ def change
+ create_table :domain_allows do |t|
+ t.string :domain, default: '', null: false, index: { unique: true }
+
+ t.timestamps
+ end
+ end
+end
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2019_07_26_175042) do
+ActiveRecord::Schema.define(version: 2019_07_28_084117) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
t.index ["account_id"], name: "index_custom_filters_on_account_id"
end
+ create_table "domain_allows", force: :cascade do |t|
+ t.string "domain", default: "", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["domain"], name: "index_domain_allows_on_domain", unique: true
+ end
+
create_table "domain_blocks", force: :cascade do |t|
t.string "domain", default: "", null: false
t.datetime "created_at", null: false
end
option :dry_run, type: :boolean
- desc 'purge DOMAIN', 'Remove accounts from a DOMAIN without a trace'
+ option :whitelist_mode, type: :boolean
+ desc 'purge [DOMAIN]', 'Remove accounts from a DOMAIN without a trace'
long_desc <<-LONG_DESC
Remove all accounts from a given DOMAIN without leaving behind any
records. Unlike a suspension, if the DOMAIN still exists in the wild,
it means the accounts could return if they are resolved again.
+
+ When the --whitelist-mode option is given, instead of purging accounts
+ from a single domain, all accounts from domains that are not whitelisted
+ are removed from the database.
LONG_DESC
- def purge(domain)
+ def purge(domain = nil)
removed = 0
dry_run = options[:dry_run] ? ' (DRY RUN)' : ''
- Account.where(domain: domain).find_each do |account|
+ scope = begin
+ if options[:whitelist_mode]
+ Account.remote.where.not(domain: DomainAllow.pluck(:domain))
+ elsif domain.present?
+ Account.remote.where(domain: domain)
+ else
+ say('No domain given', :red)
+ exit(1)
+ end
+ end
+
+ scope.find_each do |account|
SuspendAccountService.new.call(account, destroy: true) unless options[:dry_run]
removed += 1
say('.', :green, false)
--- /dev/null
+Fabricator(:domain_allow) do
+ domain "MyString"
+end
--- /dev/null
+require 'rails_helper'
+
+RSpec.describe DomainAllow, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
const fs = require('fs');
const env = process.env.NODE_ENV || 'development';
+const alwaysRequireAuth = process.env.WHITELIST_MODE === 'true' || process.env.AUTHORIZED_FETCH === 'true';
dotenv.config({
path: env === 'production' ? '.env.production' : '.env',
const wsVerifyClient = (info, cb) => {
const location = url.parse(info.req.url, true);
- const authRequired = !PUBLIC_STREAMS.some(stream => stream === location.query.stream);
+ const authRequired = alwaysRequireAuth || !PUBLIC_STREAMS.some(stream => stream === location.query.stream);
const allowedScopes = [];
if (authRequired) {
return;
}
- const authRequired = !PUBLIC_ENDPOINTS.some(endpoint => endpoint === req.path);
+ const authRequired = alwaysRequireAuth || !PUBLIC_ENDPOINTS.some(endpoint => endpoint === req.path);
const allowedScopes = [];
if (authRequired) {