* Change: #647 NGワードの入力フォーム * Wip: 画面改造 * テストコード、画面 * Fix: 複数の問題
This commit is contained in:
parent
0d2b415e26
commit
95ab1f729c
33 changed files with 526 additions and 172 deletions
|
@ -31,4 +31,5 @@ linters:
|
||||||
exclude:
|
exclude:
|
||||||
- 'app/views/application/_sidebar.html.haml'
|
- 'app/views/application/_sidebar.html.haml'
|
||||||
- 'app/views/admin/ng_rules/_ng_rule_fields.html.haml'
|
- 'app/views/admin/ng_rules/_ng_rule_fields.html.haml'
|
||||||
|
- 'app/views/admin/ng_words/keywords/_ng_word.html.haml'
|
||||||
- 'app/views/admin/sensitive_words/_sensitive_word.html.haml'
|
- 'app/views/admin/sensitive_words/_sensitive_word.html.haml'
|
||||||
|
|
30
app/controllers/admin/ng_words/keywords_controller.rb
Normal file
30
app/controllers/admin/ng_words/keywords_controller.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class NgWords::KeywordsController < NgWordsController
|
||||||
|
def show
|
||||||
|
super
|
||||||
|
@ng_words = ::NgWord.caches.presence || [::NgWord.new]
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def validate
|
||||||
|
begin
|
||||||
|
::NgWord.save_from_raws(settings_params_test)
|
||||||
|
return true
|
||||||
|
rescue
|
||||||
|
flash[:alert] = I18n.t('admin.ng_words.test_error')
|
||||||
|
redirect_to after_update_redirect_path
|
||||||
|
end
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def after_update_redirect_path
|
||||||
|
admin_ng_words_keywords_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
app/controllers/admin/ng_words/settings_controller.rb
Normal file
11
app/controllers/admin/ng_words/settings_controller.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class NgWords::SettingsController < NgWordsController
|
||||||
|
protected
|
||||||
|
|
||||||
|
def after_update_redirect_path
|
||||||
|
admin_ng_words_settings_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
app/controllers/admin/ng_words/white_list_controller.rb
Normal file
11
app/controllers/admin/ng_words/white_list_controller.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class NgWords::WhiteListController < NgWordsController
|
||||||
|
protected
|
||||||
|
|
||||||
|
def after_update_redirect_path
|
||||||
|
admin_ng_words_white_list_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,13 +11,7 @@ module Admin
|
||||||
def create
|
def create
|
||||||
authorize :ng_words, :create?
|
authorize :ng_words, :create?
|
||||||
|
|
||||||
begin
|
return unless validate
|
||||||
test_words
|
|
||||||
rescue
|
|
||||||
flash[:alert] = I18n.t('admin.ng_words.test_error')
|
|
||||||
redirect_to after_update_redirect_path
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
@admin_settings = Form::AdminSettings.new(settings_params)
|
@admin_settings = Form::AdminSettings.new(settings_params)
|
||||||
|
|
||||||
|
@ -29,19 +23,24 @@ module Admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
protected
|
||||||
|
|
||||||
def test_words
|
def validate
|
||||||
ng_words = "#{settings_params['ng_words']}\n#{settings_params['ng_words_for_stranger_mention']}".split(/\r\n|\r|\n/).filter(&:present?)
|
true
|
||||||
Admin::NgWord.reject_with_custom_words?('Sample text', ng_words)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_update_redirect_path
|
def after_update_redirect_path
|
||||||
admin_ng_words_path
|
admin_ng_words_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
def settings_params
|
def settings_params
|
||||||
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def settings_params_test
|
||||||
|
params.require(:form_admin_settings)[:ng_words_test]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ module Admin
|
||||||
authorize :sensitive_words, :create?
|
authorize :sensitive_words, :create?
|
||||||
|
|
||||||
begin
|
begin
|
||||||
test_words
|
::SensitiveWord.save_from_raws(settings_params_test)
|
||||||
rescue
|
rescue
|
||||||
flash[:alert] = I18n.t('admin.ng_words.test_error')
|
flash[:alert] = I18n.t('admin.ng_words.test_error')
|
||||||
redirect_to after_update_redirect_path
|
redirect_to after_update_redirect_path
|
||||||
|
@ -22,7 +22,7 @@ module Admin
|
||||||
|
|
||||||
@admin_settings = Form::AdminSettings.new(settings_params)
|
@admin_settings = Form::AdminSettings.new(settings_params)
|
||||||
|
|
||||||
if @admin_settings.save && ::SensitiveWord.save_from_raws(settings_params_test)
|
if @admin_settings.save
|
||||||
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
||||||
redirect_to after_update_redirect_path
|
redirect_to after_update_redirect_path
|
||||||
else
|
else
|
||||||
|
@ -32,11 +32,6 @@ module Admin
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def test_words
|
|
||||||
sensitive_words = settings_params_test['keywords'].compact.uniq
|
|
||||||
Admin::NgWord.reject_with_custom_words?('Sample text', sensitive_words)
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_update_redirect_path
|
def after_update_redirect_path
|
||||||
admin_sensitive_words_path
|
admin_sensitive_words_path
|
||||||
end
|
end
|
||||||
|
|
|
@ -320,7 +320,8 @@ Rails.delegate(
|
||||||
document,
|
document,
|
||||||
'#sensitive-words-table .add-row-button',
|
'#sensitive-words-table .add-row-button',
|
||||||
'click',
|
'click',
|
||||||
() => {
|
(ev) => {
|
||||||
|
ev.preventDefault();
|
||||||
addTableRow('sensitive-words-table');
|
addTableRow('sensitive-words-table');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -329,8 +330,24 @@ Rails.delegate(
|
||||||
document,
|
document,
|
||||||
'#sensitive-words-table .delete-row-button',
|
'#sensitive-words-table .delete-row-button',
|
||||||
'click',
|
'click',
|
||||||
({ target }) => {
|
(ev) => {
|
||||||
removeTableRow(target, 'sensitive-words-table');
|
ev.preventDefault();
|
||||||
|
removeTableRow(ev.target, 'sensitive-words-table');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Rails.delegate(document, '#ng-words-table .add-row-button', 'click', (ev) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
addTableRow('ng-words-table');
|
||||||
|
});
|
||||||
|
|
||||||
|
Rails.delegate(
|
||||||
|
document,
|
||||||
|
'#ng-words-table .delete-row-button',
|
||||||
|
'click',
|
||||||
|
(ev) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
removeTableRow(ev.target, 'ng-words-table');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -160,11 +160,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
def valid_status?
|
def valid_status?
|
||||||
valid = true
|
valid = true
|
||||||
valid = false if valid && !valid_status_for_ng_rule?
|
valid = false if valid && !valid_status_for_ng_rule?
|
||||||
valid = !Admin::NgWord.reject?("#{@params[:spoiler_text]}\n#{@params[:text]}", uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?) if valid
|
valid = !Admin::NgWord.reject?("#{@params[:spoiler_text]}\n#{@params[:text]}", uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, stranger: mention_to_local_stranger? || reference_to_local_stranger?) if valid
|
||||||
valid = !Admin::NgWord.hashtag_reject?(@tags.size, uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, text: "#{@params[:spoiler_text]}\n#{@params[:text]}") if valid
|
valid = !Admin::NgWord.hashtag_reject?(@tags.size, uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, text: "#{@params[:spoiler_text]}\n#{@params[:text]}") if valid
|
||||||
valid = !Admin::NgWord.mention_reject?(@raw_mention_uris.size, uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, text: "#{@params[:spoiler_text]}\n#{@params[:text]}") if valid
|
valid = !Admin::NgWord.mention_reject?(@raw_mention_uris.size, uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, text: "#{@params[:spoiler_text]}\n#{@params[:text]}") if valid
|
||||||
valid = !Admin::NgWord.stranger_mention_reject_with_count?(@raw_mention_uris.size, uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, text: "#{@params[:spoiler_text]}\n#{@params[:text]}") if valid && (mention_to_local_stranger? || reference_to_local_stranger?)
|
valid = !Admin::NgWord.stranger_mention_reject_with_count?(@raw_mention_uris.size, uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, text: "#{@params[:spoiler_text]}\n#{@params[:text]}") if valid && (mention_to_local_stranger? || reference_to_local_stranger?)
|
||||||
valid = !Admin::NgWord.stranger_mention_reject?("#{@params[:spoiler_text]}\n#{@params[:text]}", uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?) if valid && (mention_to_local_stranger? || reference_to_local_stranger?)
|
|
||||||
valid = false if valid && Setting.block_unfollow_account_mention && (mention_to_local_stranger? || reference_to_local_stranger?) && !local_following_sender?
|
valid = false if valid && Setting.block_unfollow_account_mention && (mention_to_local_stranger? || reference_to_local_stranger?) && !local_following_sender?
|
||||||
|
|
||||||
valid
|
valid
|
||||||
|
|
|
@ -4,20 +4,25 @@ class Admin::NgWord
|
||||||
class << self
|
class << self
|
||||||
def reject?(text, **options)
|
def reject?(text, **options)
|
||||||
text = PlainTextFormatter.new(text, false).to_s if options[:uri].present?
|
text = PlainTextFormatter.new(text, false).to_s if options[:uri].present?
|
||||||
hit_word = ng_words.detect { |word| include?(text, word) ? word : nil }
|
|
||||||
record!(:ng_words, text, hit_word, options) if hit_word.present?
|
if options.delete(:stranger)
|
||||||
hit_word.present?
|
::NgWord.caches.detect { |word| include?(text, word) ? word : nil }&.keyword.tap do |hit_word|
|
||||||
|
record!(:ng_words_for_stranger_mention, text, hit_word, options) if hit_word.present?
|
||||||
|
end.present?
|
||||||
|
else
|
||||||
|
::NgWord.caches.filter { |w| !w.stranger }.detect { |word| include?(text, word) ? word : nil }&.keyword.tap do |hit_word|
|
||||||
|
record!(:ng_words, text, hit_word, options) if hit_word.present?
|
||||||
|
end.present?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def stranger_mention_reject?(text, **options)
|
def stranger_mention_reject?(text, **options)
|
||||||
text = PlainTextFormatter.new(text, false).to_s if options[:uri].present?
|
opts = options.merge({ stranger: true })
|
||||||
hit_word = ng_words_for_stranger_mention.detect { |word| include?(text, word) ? word : nil }
|
reject?(text, **opts)
|
||||||
record!(:ng_words_for_stranger_mention, text, hit_word, options) if hit_word.present?
|
|
||||||
hit_word.present?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def reject_with_custom_words?(text, custom_ng_words)
|
def reject_with_custom_word?(text, word)
|
||||||
custom_ng_words.any? { |word| include?(text, word) }
|
include_with_regexp?(text, word)
|
||||||
end
|
end
|
||||||
|
|
||||||
def hashtag_reject?(hashtag_count, **options)
|
def hashtag_reject?(hashtag_count, **options)
|
||||||
|
@ -53,19 +58,15 @@ class Admin::NgWord
|
||||||
private
|
private
|
||||||
|
|
||||||
def include?(text, word)
|
def include?(text, word)
|
||||||
if word.start_with?('?') && word.size >= 2
|
if word.regexp
|
||||||
text =~ /#{word[1..]}/i
|
text =~ /#{word.keyword}/
|
||||||
else
|
else
|
||||||
text.include?(word)
|
text.include?(word.keyword)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def ng_words
|
def include_with_regexp?(text, word)
|
||||||
Setting.ng_words || []
|
text =~ /#{word}/i
|
||||||
end
|
|
||||||
|
|
||||||
def ng_words_for_stranger_mention
|
|
||||||
Setting.ng_words_for_stranger_mention || []
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_hash_tags_max
|
def post_hash_tags_max
|
||||||
|
|
|
@ -44,8 +44,6 @@ class Form::AdminSettings
|
||||||
delete_content_cache_without_reaction
|
delete_content_cache_without_reaction
|
||||||
status_page_url
|
status_page_url
|
||||||
captcha_enabled
|
captcha_enabled
|
||||||
ng_words
|
|
||||||
ng_words_for_stranger_mention
|
|
||||||
stranger_mention_from_local_ng
|
stranger_mention_from_local_ng
|
||||||
hide_local_users_for_anonymous
|
hide_local_users_for_anonymous
|
||||||
post_hash_tags_max
|
post_hash_tags_max
|
||||||
|
@ -122,8 +120,6 @@ class Form::AdminSettings
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
STRING_ARRAY_KEYS = %i(
|
STRING_ARRAY_KEYS = %i(
|
||||||
ng_words
|
|
||||||
ng_words_for_stranger_mention
|
|
||||||
emoji_reaction_disallow_domains
|
emoji_reaction_disallow_domains
|
||||||
permit_new_account_domains
|
permit_new_account_domains
|
||||||
).freeze
|
).freeze
|
||||||
|
|
87
app/models/ng_word.rb
Normal file
87
app/models/ng_word.rb
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ng_words
|
||||||
|
#
|
||||||
|
# id :bigint(8) not null, primary key
|
||||||
|
# keyword :string not null
|
||||||
|
# regexp :boolean default(FALSE), not null
|
||||||
|
# stranger :boolean default(TRUE), not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
|
||||||
|
class NgWord < ApplicationRecord
|
||||||
|
attr_accessor :keywords, :regexps, :strangers
|
||||||
|
|
||||||
|
validate :check_regexp
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def caches
|
||||||
|
Rails.cache.fetch('ng_words') { NgWord.where.not(id: 0).order(:keyword).to_a }
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_from_hashes(rows)
|
||||||
|
unmatched = caches
|
||||||
|
matched = []
|
||||||
|
|
||||||
|
NgWord.transaction do
|
||||||
|
rows.filter { |item| item[:keyword].present? }.each do |item|
|
||||||
|
exists = unmatched.find { |i| i.keyword == item[:keyword] }
|
||||||
|
|
||||||
|
if exists.present?
|
||||||
|
unmatched.delete(exists)
|
||||||
|
matched << exists
|
||||||
|
|
||||||
|
next if exists.regexp == item[:regexp] && exists.stranger == item[:stranger]
|
||||||
|
|
||||||
|
exists.update!(regexp: item[:regexp], stranger: item[:stranger])
|
||||||
|
elsif matched.none? { |i| i.keyword == item[:keyword] }
|
||||||
|
NgWord.create!(
|
||||||
|
keyword: item[:keyword],
|
||||||
|
regexp: item[:regexp],
|
||||||
|
stranger: item[:stranger]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
NgWord.destroy(unmatched.map(&:id))
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_from_raws(rows)
|
||||||
|
regexps = rows['regexps'] || []
|
||||||
|
strangers = rows['strangers'] || []
|
||||||
|
|
||||||
|
hashes = (rows['keywords'] || []).zip(rows['temporary_ids'] || []).map do |item|
|
||||||
|
temp_id = item[1]
|
||||||
|
{
|
||||||
|
keyword: item[0],
|
||||||
|
regexp: regexps.include?(temp_id),
|
||||||
|
stranger: strangers.include?(temp_id),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
save_from_hashes(hashes)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def invalidate_cache!
|
||||||
|
Rails.cache.delete('ng_words')
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_regexp
|
||||||
|
return if keyword.blank? || !regexp
|
||||||
|
|
||||||
|
begin
|
||||||
|
Admin::NgWord.reject_with_custom_word?('Sample text', keyword)
|
||||||
|
rescue
|
||||||
|
raise Mastodon::ValidationError, I18n.t('admin.ng_words.test_error')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,6 +16,8 @@
|
||||||
class SensitiveWord < ApplicationRecord
|
class SensitiveWord < ApplicationRecord
|
||||||
attr_accessor :keywords, :regexps, :remotes, :spoilers
|
attr_accessor :keywords, :regexps, :remotes, :spoilers
|
||||||
|
|
||||||
|
validate :check_regexp
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def caches
|
def caches
|
||||||
Rails.cache.fetch('sensitive_words') { SensitiveWord.where.not(id: 0).order(:keyword).to_a }
|
Rails.cache.fetch('sensitive_words') { SensitiveWord.where.not(id: 0).order(:keyword).to_a }
|
||||||
|
@ -50,8 +52,6 @@ class SensitiveWord < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
true
|
true
|
||||||
# rescue
|
|
||||||
# false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def save_from_raws(rows)
|
def save_from_raws(rows)
|
||||||
|
@ -78,4 +78,14 @@ class SensitiveWord < ApplicationRecord
|
||||||
def invalidate_cache!
|
def invalidate_cache!
|
||||||
Rails.cache.delete('sensitive_words')
|
Rails.cache.delete('sensitive_words')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_regexp
|
||||||
|
return if keyword.blank? || !regexp
|
||||||
|
|
||||||
|
begin
|
||||||
|
Admin::NgWord.reject_with_custom_word?('Sample text', keyword)
|
||||||
|
rescue
|
||||||
|
raise Mastodon::ValidationError, I18n.t('admin.ng_words.test_error')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -162,10 +162,9 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid_status?
|
def valid_status?
|
||||||
valid = !Admin::NgWord.reject?("#{@status_parser.spoiler_text}\n#{@status_parser.text}", uri: @status.uri, target_type: :status)
|
valid = !Admin::NgWord.reject?("#{@status_parser.spoiler_text}\n#{@status_parser.text}", uri: @status.uri, target_type: :status, stranger: mention_to_local_stranger? || reference_to_local_stranger?)
|
||||||
valid = !Admin::NgWord.hashtag_reject?(@raw_tags.size) if valid
|
valid = !Admin::NgWord.hashtag_reject?(@raw_tags.size) if valid
|
||||||
valid = false if valid && Admin::NgWord.mention_reject?(@raw_mentions.size, uri: @status.uri, target_type: :status, text: "#{@status_parser.spoiler_text}\n#{@status_parser.text}")
|
valid = false if valid && Admin::NgWord.mention_reject?(@raw_mentions.size, uri: @status.uri, target_type: :status, text: "#{@status_parser.spoiler_text}\n#{@status_parser.text}")
|
||||||
valid = false if valid && (mention_to_local_stranger? || reference_to_local_stranger?) && Admin::NgWord.stranger_mention_reject?("#{@status_parser.spoiler_text}\n#{@status_parser.text}", uri: @status.uri, target_type: :status)
|
|
||||||
valid = false if valid && (mention_to_local_stranger? || reference_to_local_stranger?) && Admin::NgWord.stranger_mention_reject_with_count?(@raw_mentions.size, uri: @status.uri, target_type: :status, text: "#{@status_parser.spoiler_text}\n#{@status_parser.text}")
|
valid = false if valid && (mention_to_local_stranger? || reference_to_local_stranger?) && Admin::NgWord.stranger_mention_reject_with_count?(@raw_mentions.size, uri: @status.uri, target_type: :status, text: "#{@status_parser.spoiler_text}\n#{@status_parser.text}")
|
||||||
valid = false if valid && (mention_to_local_stranger? || reference_to_local_stranger?) && reject_reply_exclude_followers?
|
valid = false if valid && (mention_to_local_stranger? || reference_to_local_stranger?) && reject_reply_exclude_followers?
|
||||||
|
|
||||||
|
|
10
app/views/admin/ng_words/keywords/_ng_word.html.haml
Normal file
10
app/views/admin/ng_words/keywords/_ng_word.html.haml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
- temporary_id = defined?(@temp_id) ? @temp_id += 1 : @temp_id = 1
|
||||||
|
%tr{ class: template ? 'template-row' : nil }
|
||||||
|
%td= f.input :keywords, as: :string, input_html: { multiple: true, value: ng_word.keyword }
|
||||||
|
%td
|
||||||
|
.label_input__wrapper= f.check_box :regexps, { multiple: true, checked: ng_word.regexp }, temporary_id, nil
|
||||||
|
%td
|
||||||
|
.label_input__wrapper= f.check_box :strangers, { multiple: true, checked: ng_word.stranger }, temporary_id, nil
|
||||||
|
%td
|
||||||
|
= hidden_field_tag :'form_admin_settings[ng_words_test][temporary_ids][]', temporary_id, class: 'temporary_id'
|
||||||
|
= link_to safe_join([fa_icon('times'), t('filters.index.delete')]), '#', class: 'table-action-link delete-row-button'
|
43
app/views/admin/ng_words/keywords/show.html.haml
Normal file
43
app/views/admin/ng_words/keywords/show.html.haml
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.ng_words.title')
|
||||||
|
|
||||||
|
- content_for :header_tags do
|
||||||
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
|
- content_for :heading do
|
||||||
|
%h2= t('admin.ng_words.title')
|
||||||
|
= render partial: 'admin/ng_words/shared/links'
|
||||||
|
|
||||||
|
= simple_form_for @admin_settings, url: admin_ng_words_keywords_path, html: { method: :post } do |f|
|
||||||
|
= render 'shared/error_messages', object: @admin_settings
|
||||||
|
|
||||||
|
%p.lead
|
||||||
|
= t('admin.ng_words.preamble')
|
||||||
|
= link_to t('admin.ngword_histories.title'), admin_ngword_histories_path
|
||||||
|
|
||||||
|
%p= t 'admin.ng_words.phrases.regexp_html'
|
||||||
|
%p= t 'admin.ng_words.phrases.stranger_html'
|
||||||
|
|
||||||
|
%hr/
|
||||||
|
|
||||||
|
.table-wrapper
|
||||||
|
%table.table.keywords-table#ng-words-table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th= t('simple_form.labels.defaults.phrase')
|
||||||
|
%th= t('admin.ng_words.phrases.regexp_short')
|
||||||
|
%th= t('admin.ng_words.phrases.stranger_short')
|
||||||
|
%th
|
||||||
|
%tbody
|
||||||
|
= f.simple_fields_for :ng_words_test, @ng_words do |keyword|
|
||||||
|
= render partial: 'ng_word', collection: @ng_words, locals: { f: keyword, template: false }
|
||||||
|
|
||||||
|
= f.simple_fields_for :ng_words_test, @ng_words do |keyword|
|
||||||
|
= render partial: 'ng_word', collection: [NgWord.new], locals: { f: keyword, template: true }
|
||||||
|
%tfoot
|
||||||
|
%tr
|
||||||
|
%td{ colspan: 4 }
|
||||||
|
= link_to safe_join([fa_icon('plus'), t('filters.edit.add_keyword')]), '#', class: 'table-action-link add-row-button'
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.button :button, t('generic.save_changes'), type: :submit
|
|
@ -4,21 +4,13 @@
|
||||||
- content_for :header_tags do
|
- content_for :header_tags do
|
||||||
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
= simple_form_for @admin_settings, url: admin_ng_words_path, html: { method: :post } do |f|
|
- content_for :heading do
|
||||||
|
%h2= t('admin.ng_words.title')
|
||||||
|
= render partial: 'admin/ng_words/shared/links'
|
||||||
|
|
||||||
|
= simple_form_for @admin_settings, url: admin_ng_words_settings_path, html: { method: :post } do |f|
|
||||||
= render 'shared/error_messages', object: @admin_settings
|
= render 'shared/error_messages', object: @admin_settings
|
||||||
|
|
||||||
%p.lead= t('admin.ng_words.preamble')
|
|
||||||
|
|
||||||
%p.hint
|
|
||||||
= t 'admin.ng_words.history_hint'
|
|
||||||
= link_to t('admin.ngword_histories.title'), admin_ngword_histories_path
|
|
||||||
|
|
||||||
.fields-group
|
|
||||||
= f.input :ng_words_for_stranger_mention, wrapper: :with_label, as: :text, input_html: { rows: 10 }, label: t('admin.ng_words.keywords_for_stranger_mention'), hint: t('admin.ng_words.keywords_for_stranger_mention_hint')
|
|
||||||
|
|
||||||
.fields-group
|
|
||||||
= f.input :ng_words, wrapper: :with_label, as: :text, input_html: { rows: 10 }, label: t('admin.ng_words.keywords'), hint: t('admin.ng_words.keywords_hint')
|
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :post_hash_tags_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_hash_tags_max')
|
= f.input :post_hash_tags_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_hash_tags_max')
|
||||||
|
|
||||||
|
@ -28,17 +20,6 @@
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :post_mentions_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_mentions_max')
|
= f.input :post_mentions_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_mentions_max')
|
||||||
|
|
||||||
%h4= t('admin.ng_words.white_list')
|
|
||||||
%p.lead
|
|
||||||
= t('admin.ng_words.white_list_hint')
|
|
||||||
= link_to t('admin.ng_words.remote_approval_list'), admin_accounts_path(status: 'remote_pending', origin: 'remote')
|
|
||||||
|
|
||||||
.fields-group
|
|
||||||
= f.input :hold_remote_new_accounts, wrapper: :with_label, as: :boolean, label: t('admin.ng_words.hold_remote_new_accounts'), hint: t('admin.ng_words.remote_approval_hint')
|
|
||||||
|
|
||||||
.fields-group
|
|
||||||
= f.input :permit_new_account_domains, wrapper: :with_label, as: :text, kmyblue: true, input_html: { rows: 6 }, label: t('admin.ng_words.permit_new_account_domains')
|
|
||||||
|
|
||||||
%h4= t('admin.ng_words.deprecated')
|
%h4= t('admin.ng_words.deprecated')
|
||||||
%p.hint= t('admin.ng_words.deprecated_hint')
|
%p.hint= t('admin.ng_words.deprecated_hint')
|
||||||
|
|
6
app/views/admin/ng_words/shared/_links.html.haml
Normal file
6
app/views/admin/ng_words/shared/_links.html.haml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.content__heading__tabs
|
||||||
|
= render_navigation renderer: :links do |primary|
|
||||||
|
:ruby
|
||||||
|
primary.item :keywords, safe_join([fa_icon('pencil fw'), t('admin.ng_words.keywords')]), admin_ng_words_keywords_path
|
||||||
|
primary.item :white_list, safe_join([fa_icon('list fw'), t('admin.ng_words.white_list')]), admin_ng_words_white_list_path
|
||||||
|
primary.item :settings, safe_join([fa_icon('cog fw'), t('admin.ng_words.settings')]), admin_ng_words_settings_path
|
25
app/views/admin/ng_words/white_list/show.html.haml
Normal file
25
app/views/admin/ng_words/white_list/show.html.haml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.ng_words.title')
|
||||||
|
|
||||||
|
- content_for :header_tags do
|
||||||
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
|
- content_for :heading do
|
||||||
|
%h2= t('admin.ng_words.title')
|
||||||
|
= render partial: 'admin/ng_words/shared/links'
|
||||||
|
|
||||||
|
= simple_form_for @admin_settings, url: admin_ng_words_white_list_path, html: { method: :post } do |f|
|
||||||
|
= render 'shared/error_messages', object: @admin_settings
|
||||||
|
|
||||||
|
%p.lead
|
||||||
|
= t('admin.ng_words.white_list_hint')
|
||||||
|
= link_to t('admin.ng_words.remote_approval_list'), admin_accounts_path(status: 'remote_pending', origin: 'remote')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :hold_remote_new_accounts, wrapper: :with_label, as: :boolean, label: t('admin.ng_words.hold_remote_new_accounts'), hint: t('admin.ng_words.remote_approval_hint')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :permit_new_account_domains, wrapper: :with_label, as: :text, kmyblue: true, input_html: { rows: 6 }, label: t('admin.ng_words.permit_new_account_domains')
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.button :button, t('generic.save_changes'), type: :submit
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
.filters
|
.filters
|
||||||
.back-link
|
.back-link
|
||||||
= link_to admin_ng_words_path do
|
= link_to admin_ng_words_keywords_path do
|
||||||
= fa_icon 'chevron-left fw'
|
= fa_icon 'chevron-left fw'
|
||||||
= t('admin.ngword_histories.back_to_ng_words')
|
= t('admin.ngword_histories.back_to_ng_words')
|
||||||
|
|
||||||
|
|
|
@ -751,19 +751,21 @@ en:
|
||||||
deprecated_hint: These settings will be removed in the next LTS or kmyblue version 14.0, whichever comes first. Please refer to the description of each setting and replace them with the new settings if possible.
|
deprecated_hint: These settings will be removed in the next LTS or kmyblue version 14.0, whichever comes first. Please refer to the description of each setting and replace them with the new settings if possible.
|
||||||
hide_local_users_for_anonymous: Hide timeline local user posts from anonymous
|
hide_local_users_for_anonymous: Hide timeline local user posts from anonymous
|
||||||
hide_local_users_for_anonymous_hint: この設定は削除予定です。設定削除後は、常にチェックをつけていない場合と同じ挙動になります。サーバー設定の「見つける」にある「公開タイムラインへの未認証のアクセスを許可する」で、完全ではありませんが代替可能です。
|
hide_local_users_for_anonymous_hint: この設定は削除予定です。設定削除後は、常にチェックをつけていない場合と同じ挙動になります。サーバー設定の「見つける」にある「公開タイムラインへの未認証のアクセスを許可する」で、完全ではありませんが代替可能です。
|
||||||
history_hint: We recommend that you regularly check your NG words to make sure that you have not specified the NG words incorrectly.
|
|
||||||
hold_remote_new_accounts: Hold new remote accounts
|
hold_remote_new_accounts: Hold new remote accounts
|
||||||
keywords: Reject keywords
|
keywords: Reject keywords
|
||||||
keywords_for_stranger_mention: Reject keywords when mention/reply/reference/quote from strangers
|
|
||||||
keywords_for_stranger_mention_hint: This words are checked posts from other servers only.
|
|
||||||
keywords_hint: The first character of the line is "?". to use regular expressions
|
|
||||||
permit_new_account_domains: Domain list to automatically approve new users
|
permit_new_account_domains: Domain list to automatically approve new users
|
||||||
preamble: This setting is useful for solving problems related to spam that are difficult to address with domain blocking. You can reject posts that contain specific keywords or too many mentions. Please consider your settings carefully to avoid deleting problematic posts. More detailed settings can be made by using "NG Rules".
|
preamble: This setting is useful for solving problems related to spam that are difficult to address with domain blocking. You can reject posts that meet certain criteria, such as the inclusion of specific keywords. Please consider your settings carefully and check your history regularly to ensure that problem-free submissions are not deleted.
|
||||||
post_hash_tags_max: Hash tags max for posts
|
post_hash_tags_max: Hash tags max for posts
|
||||||
post_mentions_max: Mentions max for posts
|
post_mentions_max: Mentions max for posts
|
||||||
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (If the mentions include at least one person who is not a follower of yours)
|
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (If the mentions include at least one person who is not a follower of yours)
|
||||||
|
phrases:
|
||||||
|
regexp_html: <strong>正規</strong> 表現 にチェックの入っている項目は、正規表現を用いての比較となります。
|
||||||
|
regexp_short: 正規
|
||||||
|
stranger_html: <strong>無関</strong> 係のフォロワーからのメンション にチェックの入っている項目は、フォロー関係にないアカウントからのメンション、返信、参照などのみに適用されます。
|
||||||
|
stranger_short: 無関
|
||||||
remote_approval_list: List of remote accounts awaiting approval
|
remote_approval_list: List of remote accounts awaiting approval
|
||||||
remote_approval_hint: Newly recognized accounts with unspecified domains will be placed in Suspended status. You can review that list and approve them if necessary. If this setting is not enabled, all remote accounts will be approved immediately.
|
remote_approval_hint: Newly recognized accounts with unspecified domains will be placed in Suspended status. You can review that list and approve them if necessary. If this setting is not enabled, all remote accounts will be approved immediately.
|
||||||
|
settings: Settings
|
||||||
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
||||||
stranger_mention_from_local_ng_hint: この設定は削除予定です。設定削除後は、常にチェックをつけている場合と同じ挙動になります。この動作を希望しない場合は、NGルールで代替してください。
|
stranger_mention_from_local_ng_hint: この設定は削除予定です。設定削除後は、常にチェックをつけている場合と同じ挙動になります。この動作を希望しない場合は、NGルールで代替してください。
|
||||||
test_error: Testing is returned any errors
|
test_error: Testing is returned any errors
|
||||||
|
|
|
@ -684,7 +684,7 @@ ja:
|
||||||
empty: NGルールが空です
|
empty: NGルールが空です
|
||||||
empty_title: 空のタイトル
|
empty_title: 空のタイトル
|
||||||
hit_count: ここ一週間で %{count} 件の検出
|
hit_count: ここ一週間で %{count} 件の検出
|
||||||
preamble: スパムの中にはどうしても緩すぎる条件を指定しなければならず、他の正常な投稿が規制に巻き込まれやすくなる場合があります。NGルールではアカウントや投稿の特徴などを詳細に指定して、巻き込まれる投稿を少しでも減らすことができます。設定は慎重に検討し、正常な投稿の巻き込みが最小限になるよう定期的に履歴を確認してください。
|
preamble: 「NGワードとスパム」機能においてどうしても緩すぎる条件を指定しなければならず、他の正常な投稿が規制に巻き込まれやすくなる場合があります。NGルールではアカウントや投稿の特徴などを詳細に指定して、巻き込まれる投稿を少しでも減らすことができます。設定は慎重に検討し、正常な投稿の巻き込みが最小限になるよう定期的に履歴を確認してください。
|
||||||
title: NGルール
|
title: NGルール
|
||||||
new:
|
new:
|
||||||
save: 新規NGルールを保存
|
save: 新規NGルールを保存
|
||||||
|
@ -750,19 +750,21 @@ ja:
|
||||||
deprecated_hint: これらの設定は、次回のLTS、またはkmyblueバージョン14.0のどちらか早い方で削除する予定です。それぞれの設定の説明を参照して、可能であれば新しい設定に置き換えてください。
|
deprecated_hint: これらの設定は、次回のLTS、またはkmyblueバージョン14.0のどちらか早い方で削除する予定です。それぞれの設定の説明を参照して、可能であれば新しい設定に置き換えてください。
|
||||||
hide_local_users_for_anonymous: ログインしていない状態でローカルユーザーの投稿をタイムラインから取得できないようにする
|
hide_local_users_for_anonymous: ログインしていない状態でローカルユーザーの投稿をタイムラインから取得できないようにする
|
||||||
hide_local_users_for_anonymous_hint: この設定は削除予定です。設定削除後は、常にチェックをつけていない場合と同じ挙動になります。サーバー設定の「見つける」にある「公開タイムラインへの未認証のアクセスを許可する」で、完全ではありませんが代替可能です。
|
hide_local_users_for_anonymous_hint: この設定は削除予定です。設定削除後は、常にチェックをつけていない場合と同じ挙動になります。サーバー設定の「見つける」にある「公開タイムラインへの未認証のアクセスを許可する」で、完全ではありませんが代替可能です。
|
||||||
history_hint: 設定されたNGワードによって実際に拒否された投稿などは、履歴より確認できます。NGワードの指定に誤りがないか定期的に確認することをおすすめします。
|
|
||||||
hold_remote_new_accounts: リモートの新規アカウントを保留する
|
hold_remote_new_accounts: リモートの新規アカウントを保留する
|
||||||
keywords: 投稿できないキーワード
|
keywords: 拒否するキーワード
|
||||||
keywords_for_stranger_mention: フォローしていないアカウントへのメンションや参照で利用できないキーワード
|
|
||||||
keywords_for_stranger_mention_hint: フォローしていないアカウントへのメンション、参照、引用にのみ適用されます
|
|
||||||
keywords_hint: 行を「?」で始めると、正規表現が使えます
|
|
||||||
permit_new_account_domains: 新規ユーザーを自動承認するドメイン
|
permit_new_account_domains: 新規ユーザーを自動承認するドメイン
|
||||||
preamble: ドメインブロックでは対処の難しいスパムに関する問題の解決に、この設定が役に立ちます。特定キーワードが含まれていたり、メンション数が多すぎたりする投稿を拒否することができます。問題のない投稿が削除されないよう、設定は慎重に検討してください。「NGルール」を用いることで、さらに細かい設定が可能です。
|
phrases:
|
||||||
|
regexp_html: <strong>正規</strong> 表現 にチェックの入っている項目は、正規表現を用いての比較となります。
|
||||||
|
regexp_short: 正規
|
||||||
|
stranger_html: <strong>無関</strong> 係のフォロワーからのメンション にチェックの入っている項目は、フォロー関係にないアカウントからのメンション、返信、参照などのみに適用されます。
|
||||||
|
stranger_short: 無関
|
||||||
|
preamble: ドメインブロックでは対処の難しいスパムに関する問題の解決に、この設定が役に立ちます。特定キーワードが含まれているなどの条件を満たした投稿を拒否することができます。問題のない投稿が削除されないよう設定は慎重に検討し、定期的に履歴を確認してください。
|
||||||
post_hash_tags_max: 投稿に設定可能なハッシュタグの最大数
|
post_hash_tags_max: 投稿に設定可能なハッシュタグの最大数
|
||||||
post_mentions_max: 投稿に設定可能なメンションの最大数
|
post_mentions_max: 投稿に設定可能なメンションの最大数
|
||||||
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (メンション先にフォロワー以外を1人でも含む場合)
|
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (メンション先にフォロワー以外を1人でも含む場合)
|
||||||
remote_approval_list: 承認待ちのリモートアカウント一覧
|
remote_approval_list: 承認待ちのリモートアカウント一覧
|
||||||
remote_approval_hint: 指定されていないドメインで新しく認識されたアカウントはサスペンド状態になります。その一覧を確認し、必要であれば承認を行うことができます。この設定が有効でない場合、全てのリモートアカウントが即座に承認されます。
|
remote_approval_hint: 指定されていないドメインで新しく認識されたアカウントはサスペンド状態になります。その一覧を確認し、必要であれば承認を行うことができます。この設定が有効でない場合、全てのリモートアカウントが即座に承認されます。
|
||||||
|
settings: 詳細設定
|
||||||
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
||||||
stranger_mention_from_local_ng_hint: この設定は削除予定です。設定削除後は、常にチェックをつけている場合と同じ挙動になります。この動作を希望しない場合は、NGルールで代替してください。
|
stranger_mention_from_local_ng_hint: この設定は削除予定です。設定削除後は、常にチェックをつけている場合と同じ挙動になります。この動作を希望しない場合は、NGルールで代替してください。
|
||||||
test_error: NGワードのテストに失敗しました。正規表現のミスが含まれているかもしれません
|
test_error: NGワードのテストに失敗しました。正規表現のミスが含まれているかもしれません
|
||||||
|
|
|
@ -49,7 +49,7 @@ SimpleNavigation::Configuration.run do |navigation|
|
||||||
n.item :moderation, safe_join([fa_icon('gavel fw'), t('moderation.title')]), nil, if: -> { current_user.can?(:manage_reports, :view_audit_log, :manage_users, :manage_invites, :manage_taxonomies, :manage_federation, :manage_blocks, :manage_ng_words, :manage_sensitive_words) && !self_destruct } do |s|
|
n.item :moderation, safe_join([fa_icon('gavel fw'), t('moderation.title')]), nil, if: -> { current_user.can?(:manage_reports, :view_audit_log, :manage_users, :manage_invites, :manage_taxonomies, :manage_federation, :manage_blocks, :manage_ng_words, :manage_sensitive_words) && !self_destruct } do |s|
|
||||||
s.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_path, highlights_on: %r{/admin/reports}, if: -> { current_user.can?(:manage_reports) }
|
s.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_path, highlights_on: %r{/admin/reports}, if: -> { current_user.can?(:manage_reports) }
|
||||||
s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_path(origin: 'local'), highlights_on: %r{/admin/accounts|/admin/pending_accounts|/admin/disputes|/admin/users}, if: -> { current_user.can?(:manage_users) }
|
s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_path(origin: 'local'), highlights_on: %r{/admin/accounts|/admin/pending_accounts|/admin/disputes|/admin/users}, if: -> { current_user.can?(:manage_users) }
|
||||||
s.item :ng_words, safe_join([fa_icon('list fw'), t('admin.ng_words.title')]), admin_ng_words_path, highlights_on: %r{/admin/(ng_words|ngword_histories)}, if: -> { current_user.can?(:manage_ng_words) }
|
s.item :ng_words, safe_join([fa_icon('list fw'), t('admin.ng_words.title')]), admin_ng_words_keywords_path, highlights_on: %r{/admin/(ng_words|ngword_histories)}, if: -> { current_user.can?(:manage_ng_words) }
|
||||||
s.item :ng_rules, safe_join([fa_icon('rub fw'), t('admin.ng_rules.title')]), admin_ng_rules_path, highlights_on: %r{/admin/(ng_rules|ng_rule_histories)}, if: -> { current_user.can?(:manage_ng_words) }
|
s.item :ng_rules, safe_join([fa_icon('rub fw'), t('admin.ng_rules.title')]), admin_ng_rules_path, highlights_on: %r{/admin/(ng_rules|ng_rule_histories)}, if: -> { current_user.can?(:manage_ng_words) }
|
||||||
s.item :sensitive_words, safe_join([fa_icon('list fw'), t('admin.sensitive_words.title')]), admin_sensitive_words_path, highlights_on: %r{/admin/sensitive_words}, if: -> { current_user.can?(:manage_sensitive_words) }
|
s.item :sensitive_words, safe_join([fa_icon('list fw'), t('admin.sensitive_words.title')]), admin_sensitive_words_path, highlights_on: %r{/admin/sensitive_words}, if: -> { current_user.can?(:manage_sensitive_words) }
|
||||||
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) }
|
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) }
|
||||||
|
|
|
@ -32,7 +32,11 @@ namespace :admin do
|
||||||
|
|
||||||
resources :action_logs, only: [:index]
|
resources :action_logs, only: [:index]
|
||||||
resources :warning_presets, except: [:new, :show]
|
resources :warning_presets, except: [:new, :show]
|
||||||
resource :ng_words, only: [:show, :create]
|
namespace :ng_words do
|
||||||
|
resource :keywords, only: [:show, :create], controller: 'keywords'
|
||||||
|
resource :white_list, only: [:show, :create], controller: 'white_list'
|
||||||
|
resource :settings, only: [:show, :create], controller: 'settings'
|
||||||
|
end
|
||||||
resources :ngword_histories, only: [:index]
|
resources :ngword_histories, only: [:index]
|
||||||
resources :ng_rules, except: [:show] do
|
resources :ng_rules, except: [:show] do
|
||||||
member do
|
member do
|
||||||
|
|
63
db/migrate/20240320231633_create_ng_words.rb
Normal file
63
db/migrate/20240320231633_create_ng_words.rb
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CreateNgWords < ActiveRecord::Migration[7.1]
|
||||||
|
class Setting < ApplicationRecord
|
||||||
|
def value
|
||||||
|
YAML.safe_load(self[:value], permitted_classes: [ActiveSupport::HashWithIndifferentAccess, Symbol]) if self[:value].present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def value=(new_value)
|
||||||
|
self[:value] = new_value.to_yaml
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class NgWord < ApplicationRecord; end
|
||||||
|
|
||||||
|
def normalized_keyword(keyword)
|
||||||
|
if regexp?(keyword)
|
||||||
|
keyword[1..]
|
||||||
|
else
|
||||||
|
keyword
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def regexp?(keyword)
|
||||||
|
keyword.start_with?('?') && keyword.size >= 2
|
||||||
|
end
|
||||||
|
|
||||||
|
def up
|
||||||
|
create_table :ng_words do |t|
|
||||||
|
t.string :keyword, null: false
|
||||||
|
t.boolean :regexp, null: false, default: false
|
||||||
|
t.boolean :stranger, null: false, default: true
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
settings = Setting.where(var: %i(ng_words ng_words_for_stranger_mention))
|
||||||
|
ng_words = settings.find { |s| s.var == 'ng_words' }&.value&.compact_blank&.uniq || []
|
||||||
|
ng_words_for_stranger_mention = settings.find { |s| s.var == 'ng_words_for_stranger_mention' }&.value&.compact_blank&.uniq || []
|
||||||
|
|
||||||
|
(ng_words + ng_words_for_stranger_mention).compact.uniq.each do |word|
|
||||||
|
NgWord.create!(
|
||||||
|
keyword: normalized_keyword(word),
|
||||||
|
regexp: regexp?(word),
|
||||||
|
stranger: ng_words_for_stranger_mention.include?(word)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
settings.destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
ng_words = NgWord.where(stranger: false).map { |s| s.regexp ? "?#{s.keyword}" : s.keyword }
|
||||||
|
ng_words_for_stranger_mention = NgWord.where(stranger: true).map { |s| s.regexp ? "?#{s.keyword}" : s.keyword }
|
||||||
|
|
||||||
|
Setting.where(var: %i(ng_words ng_words_for_stranger_mention)).destroy_all
|
||||||
|
|
||||||
|
Setting.new(var: :ng_words).tap { |s| s.value = ng_words }.save!
|
||||||
|
Setting.new(var: :ng_words_for_stranger_mention).tap { |s| s.value = ng_words_for_stranger_mention }.save!
|
||||||
|
|
||||||
|
drop_table :ng_words
|
||||||
|
end
|
||||||
|
end
|
10
db/schema.rb
10
db/schema.rb
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2024_03_12_230204) do
|
ActiveRecord::Schema[7.1].define(version: 2024_03_20_231633) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
@ -926,6 +926,14 @@ ActiveRecord::Schema[7.1].define(version: 2024_03_12_230204) do
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "ng_words", force: :cascade do |t|
|
||||||
|
t.string "keyword", null: false
|
||||||
|
t.boolean "regexp", default: false, null: false
|
||||||
|
t.boolean "stranger", default: true, null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "ngword_histories", force: :cascade do |t|
|
create_table "ngword_histories", force: :cascade do |t|
|
||||||
t.string "uri", null: false
|
t.string "uri", null: false
|
||||||
t.integer "target_type", null: false
|
t.integer "target_type", null: false
|
||||||
|
|
|
@ -94,6 +94,7 @@ namespace :dangerous do
|
||||||
20240227225017
|
20240227225017
|
||||||
20240229233617
|
20240229233617
|
||||||
20240312230204
|
20240312230204
|
||||||
|
20240320231633
|
||||||
)
|
)
|
||||||
# Removed: account_groups
|
# Removed: account_groups
|
||||||
target_tables = %w(
|
target_tables = %w(
|
||||||
|
@ -113,6 +114,7 @@ namespace :dangerous do
|
||||||
ng_rules
|
ng_rules
|
||||||
ng_rule_histories
|
ng_rule_histories
|
||||||
ngword_histories
|
ngword_histories
|
||||||
|
ng_words
|
||||||
pending_follow_requests
|
pending_follow_requests
|
||||||
pending_statuses
|
pending_statuses
|
||||||
scheduled_expiration_statuses
|
scheduled_expiration_statuses
|
||||||
|
|
5
spec/fabricators/ng_word_fabricator.rb
Normal file
5
spec/fabricators/ng_word_fabricator.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
Fabricator(:ng_word) do
|
||||||
|
keyword { sequence(:keyword) { |i| "keyword_#{i}" } }
|
||||||
|
end
|
|
@ -1755,8 +1755,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
let(:custom_before) { true }
|
let(:custom_before) { true }
|
||||||
let(:custom_before_sub) { false }
|
let(:custom_before_sub) { false }
|
||||||
let(:content) { 'Lorem ipsum' }
|
let(:content) { 'Lorem ipsum' }
|
||||||
let(:ng_words) { 'hello' }
|
let(:ng_word) { 'hello' }
|
||||||
let(:ng_words_for_stranger_mention) { 'ohagi' }
|
let(:ng_word_for_stranger_mention) { 'ohagi' }
|
||||||
let(:object_json) do
|
let(:object_json) do
|
||||||
{
|
{
|
||||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||||
|
@ -1767,7 +1767,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Form::AdminSettings.new(ng_words: ng_words, ng_words_for_stranger_mention: ng_words_for_stranger_mention).save
|
Fabricate(:ng_word, keyword: ng_word, stranger: false)
|
||||||
|
Fabricate(:ng_word, keyword: ng_word_for_stranger_mention, stranger: true)
|
||||||
subject.perform unless custom_before_sub
|
subject.perform unless custom_before_sub
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1777,11 +1778,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to_not be_nil
|
expect(sender.statuses.first).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not record history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to be_nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when hit ng words' do
|
context 'when hit ng words' do
|
||||||
|
@ -1796,7 +1792,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
expect(history).to_not be_nil
|
expect(history).to_not be_nil
|
||||||
expect(history.status_blocked?).to be true
|
expect(history.status_blocked?).to be true
|
||||||
expect(history.within_ng_words?).to be true
|
expect(history.within_ng_words?).to be true
|
||||||
expect(history.keyword).to eq ng_words
|
expect(history.keyword).to eq ng_word
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1813,11 +1809,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to be_nil
|
expect(sender.statuses.first).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'records history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to be_nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when mention from tags' do
|
context 'when mention from tags' do
|
||||||
|
@ -1844,11 +1835,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to_not be_nil
|
expect(sender.statuses.first).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not record history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to be_nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with using ng words for stranger' do
|
context 'with using ng words for stranger' do
|
||||||
|
@ -1857,14 +1843,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to be_nil
|
expect(sender.statuses.first).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'records history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to_not be_nil
|
|
||||||
expect(history.status_blocked?).to be true
|
|
||||||
expect(history.within_ng_words_for_stranger_mention?).to be true
|
|
||||||
expect(history.keyword).to eq ng_words_for_stranger_mention
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with using ng words for stranger but receiver is following him' do
|
context 'with using ng words for stranger but receiver is following him' do
|
||||||
|
@ -1879,11 +1857,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to_not be_nil
|
expect(sender.statuses.first).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not record history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to be_nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with using ng words for stranger but multiple receivers are partically following him' do
|
context 'with using ng words for stranger but multiple receivers are partically following him' do
|
||||||
|
@ -1917,14 +1890,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to be_nil
|
expect(sender.statuses.first).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'records history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to_not be_nil
|
|
||||||
expect(history.status_blocked?).to be true
|
|
||||||
expect(history.within_ng_words_for_stranger_mention?).to be true
|
|
||||||
expect(history.keyword).to eq ng_words_for_stranger_mention
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1946,14 +1911,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to be_nil
|
expect(sender.statuses.first).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'records history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to_not be_nil
|
|
||||||
expect(history.status_blocked?).to be true
|
|
||||||
expect(history.within_ng_words_for_stranger_mention?).to be true
|
|
||||||
expect(history.keyword).to eq ng_words_for_stranger_mention
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with following' do
|
context 'with following' do
|
||||||
|
@ -1967,11 +1924,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to_not be_nil
|
expect(sender.statuses.first).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not record history' do
|
|
||||||
history = NgwordHistory.find_by(uri: object_json[:id])
|
|
||||||
expect(history).to be_nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
77
spec/models/admin/ng_word_spec.rb
Normal file
77
spec/models/admin/ng_word_spec.rb
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Admin::NgWord do
|
||||||
|
describe '#reject?' do
|
||||||
|
subject { described_class.reject?(text, stranger: stranger, uri: uri, target_type: :status) }
|
||||||
|
|
||||||
|
let(:text) { 'This is a ohagi.' }
|
||||||
|
let(:stranger) { false }
|
||||||
|
let(:uri) { nil }
|
||||||
|
|
||||||
|
context 'when general post' do
|
||||||
|
it 'ng word hits' do
|
||||||
|
Fabricate(:ng_word, keyword: 'ohagi', stranger: false)
|
||||||
|
expect(subject).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'else ng word does not hit' do
|
||||||
|
Fabricate(:ng_word, keyword: 'angry', stranger: false)
|
||||||
|
expect(subject).to be false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'stranger word does not hit' do
|
||||||
|
Fabricate(:ng_word, keyword: 'ohagi', stranger: true)
|
||||||
|
expect(subject).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when mention to stranger' do
|
||||||
|
let(:stranger) { true }
|
||||||
|
|
||||||
|
it 'ng word hits' do
|
||||||
|
Fabricate(:ng_word, keyword: 'ohagi', stranger: true)
|
||||||
|
expect(subject).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'else ng word does not hit' do
|
||||||
|
Fabricate(:ng_word, keyword: 'angry', stranger: true)
|
||||||
|
expect(subject).to be false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'general word hits' do
|
||||||
|
Fabricate(:ng_word, keyword: 'ohagi', stranger: false)
|
||||||
|
expect(subject).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when remote post' do
|
||||||
|
let(:uri) { 'https://example.com/note' }
|
||||||
|
|
||||||
|
it 'ng word hits' do
|
||||||
|
Fabricate(:ng_word, keyword: 'ohagi', stranger: false)
|
||||||
|
expect(subject).to be true
|
||||||
|
expect(NgwordHistory.find_by(uri: uri)).to_not be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'else ng word does not hit' do
|
||||||
|
Fabricate(:ng_word, keyword: 'angry', stranger: false)
|
||||||
|
expect(subject).to be false
|
||||||
|
expect(NgwordHistory.find_by(uri: uri)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when using regexp' do
|
||||||
|
it 'regexp hits with enable' do
|
||||||
|
Fabricate(:ng_word, keyword: 'oha[ghi]i', regexp: true, stranger: false)
|
||||||
|
expect(subject).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'regexp does not hit without enable' do
|
||||||
|
Fabricate(:ng_word, keyword: 'oha[ghi]i', regexp: false, stranger: false)
|
||||||
|
expect(subject).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -425,7 +425,7 @@ RSpec.describe ActivityPub::ProcessAccountService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates account when ng word is not set' do
|
it 'creates account when ng word is not set' do
|
||||||
Setting.ng_words = ['Amazon']
|
Fabricate(:ng_word, keyword: 'Amazon', stranger: false)
|
||||||
subject
|
subject
|
||||||
expect(account.reload.display_name).to eq 'Ohagi'
|
expect(account.reload.display_name).to eq 'Ohagi'
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ RSpec.describe ActivityPub::ProcessAccountService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not create account when ng word is set' do
|
it 'does not create account when ng word is set' do
|
||||||
Setting.ng_words = ['Ohagi']
|
Fabricate(:ng_word, keyword: 'Ohagi', stranger: false)
|
||||||
subject
|
subject
|
||||||
expect(account.reload.display_name).to_not eq 'Ohagi'
|
expect(account.reload.display_name).to_not eq 'Ohagi'
|
||||||
|
|
||||||
|
|
|
@ -515,7 +515,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
let(:content) { 'ng word test' }
|
let(:content) { 'ng word test' }
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words: 'test').save
|
Fabricate(:ng_word, keyword: 'test', stranger: false)
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to_not eq content
|
expect(status.reload.text).to_not eq content
|
||||||
|
@ -526,7 +526,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
let(:content) { 'ng word aiueo' }
|
let(:content) { 'ng word aiueo' }
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words: 'test').save
|
Fabricate(:ng_word, keyword: 'test', stranger: false)
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to eq content
|
expect(status.reload.text).to eq content
|
||||||
|
@ -542,7 +542,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
let(:content) { 'ng word test' }
|
let(:content) { 'ng word test' }
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to_not eq content
|
expect(status.reload.text).to_not eq content
|
||||||
|
@ -550,7 +551,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'update status when following' do
|
it 'update status when following' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
alice.follow!(status.account)
|
alice.follow!(status.account)
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
|
@ -568,7 +570,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
let(:content) { 'ng word test' }
|
let(:content) { 'ng word test' }
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '0').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '0').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to_not eq content
|
expect(status.reload.text).to_not eq content
|
||||||
|
@ -589,7 +592,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test').save
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to eq content
|
expect(status.reload.text).to eq content
|
||||||
|
@ -607,7 +610,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
let(:thread) { Fabricate(:status, account: alice) }
|
let(:thread) { Fabricate(:status, account: alice) }
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test').save
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to_not eq content
|
expect(status.reload.text).to_not eq content
|
||||||
|
@ -629,7 +632,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test').save
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to eq content
|
expect(status.reload.text).to eq content
|
||||||
|
@ -658,7 +661,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
let(:content) { 'ng word test' }
|
let(:content) { 'ng word test' }
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to_not eq content
|
expect(status.reload.text).to_not eq content
|
||||||
|
@ -671,7 +675,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'update status' do
|
it 'update status' do
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test').save
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
expect(status.reload.text).to eq content
|
expect(status.reload.text).to eq content
|
||||||
|
|
|
@ -613,7 +613,7 @@ RSpec.describe PostStatusService do
|
||||||
it 'hit ng words' do
|
it 'hit ng words' do
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
text = 'ng word test'
|
text = 'ng word test'
|
||||||
Form::AdminSettings.new(ng_words: 'test').save
|
Fabricate(:ng_word, keyword: 'test', stranger: false)
|
||||||
|
|
||||||
expect { subject.call(account, text: text) }.to raise_error(Mastodon::ValidationError)
|
expect { subject.call(account, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||||
end
|
end
|
||||||
|
@ -621,7 +621,7 @@ RSpec.describe PostStatusService do
|
||||||
it 'not hit ng words' do
|
it 'not hit ng words' do
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
text = 'ng word aiueo'
|
text = 'ng word aiueo'
|
||||||
Form::AdminSettings.new(ng_words: 'test').save
|
Fabricate(:ng_word, keyword: 'test', stranger: false)
|
||||||
|
|
||||||
status = subject.call(account, text: text)
|
status = subject.call(account, text: text)
|
||||||
|
|
||||||
|
@ -633,7 +633,8 @@ RSpec.describe PostStatusService do
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
text = 'ng word test @ohagi'
|
text = 'ng word test @ohagi'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test', stranger: true)
|
||||||
|
|
||||||
expect { subject.call(account, text: text) }.to raise_error(Mastodon::ValidationError)
|
expect { subject.call(account, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||||
end
|
end
|
||||||
|
@ -642,7 +643,8 @@ RSpec.describe PostStatusService do
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
text = 'ng word test @ohagi'
|
text = 'ng word test @ohagi'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '0').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '0').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test', stranger: true)
|
||||||
|
|
||||||
status = subject.call(account, text: text)
|
status = subject.call(account, text: text)
|
||||||
|
|
||||||
|
@ -655,7 +657,8 @@ RSpec.describe PostStatusService do
|
||||||
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
mentioned.follow!(account)
|
mentioned.follow!(account)
|
||||||
text = 'ng word test @ohagi'
|
text = 'ng word test @ohagi'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test', stranger: true)
|
||||||
|
|
||||||
status = subject.call(account, text: text)
|
status = subject.call(account, text: text)
|
||||||
|
|
||||||
|
@ -666,7 +669,8 @@ RSpec.describe PostStatusService do
|
||||||
it 'hit ng words for reply' do
|
it 'hit ng words for reply' do
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
text = 'ng word test'
|
text = 'ng word test'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test', stranger: true)
|
||||||
|
|
||||||
expect { subject.call(account, text: text, thread: Fabricate(:status)) }.to raise_error(Mastodon::ValidationError)
|
expect { subject.call(account, text: text, thread: Fabricate(:status)) }.to raise_error(Mastodon::ValidationError)
|
||||||
end
|
end
|
||||||
|
@ -676,7 +680,8 @@ RSpec.describe PostStatusService do
|
||||||
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
mentioned.follow!(account)
|
mentioned.follow!(account)
|
||||||
text = 'ng word test'
|
text = 'ng word test'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test', stranger: true)
|
||||||
|
|
||||||
status = subject.call(account, text: text)
|
status = subject.call(account, text: text)
|
||||||
|
|
||||||
|
@ -702,7 +707,8 @@ RSpec.describe PostStatusService do
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test', stranger: true)
|
||||||
|
|
||||||
expect { subject.call(account, text: text) }.to raise_error(Mastodon::ValidationError)
|
expect { subject.call(account, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||||
end
|
end
|
||||||
|
@ -713,7 +719,8 @@ RSpec.describe PostStatusService do
|
||||||
target_status.account.follow!(account)
|
target_status.account.follow!(account)
|
||||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test', stranger: true)
|
||||||
|
|
||||||
status = subject.call(account, text: text)
|
status = subject.call(account, text: text)
|
||||||
|
|
||||||
|
|
|
@ -272,14 +272,14 @@ RSpec.describe UpdateStatusService do
|
||||||
|
|
||||||
it 'hit ng words' do
|
it 'hit ng words' do
|
||||||
text = 'ng word test'
|
text = 'ng word test'
|
||||||
Form::AdminSettings.new(ng_words: 'test').save
|
Fabricate(:ng_word, keyword: 'test', stranger: false)
|
||||||
|
|
||||||
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
|
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'not hit ng words' do
|
it 'not hit ng words' do
|
||||||
text = 'ng word aiueo'
|
text = 'ng word aiueo'
|
||||||
Form::AdminSettings.new(ng_words: 'test').save
|
Fabricate(:ng_word, keyword: 'test', stranger: false)
|
||||||
|
|
||||||
status2 = subject.call(status, status.account_id, text: text)
|
status2 = subject.call(status, status.account_id, text: text)
|
||||||
|
|
||||||
|
@ -290,7 +290,8 @@ RSpec.describe UpdateStatusService do
|
||||||
it 'hit ng words for mention' do
|
it 'hit ng words for mention' do
|
||||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
text = 'ng word test @ohagi'
|
text = 'ng word test @ohagi'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
|
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||||
expect(status.reload.text).to_not eq text
|
expect(status.reload.text).to_not eq text
|
||||||
|
@ -300,7 +301,8 @@ RSpec.describe UpdateStatusService do
|
||||||
it 'hit ng words for mention but local posts are not checked' do
|
it 'hit ng words for mention but local posts are not checked' do
|
||||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
text = 'ng word test @ohagi'
|
text = 'ng word test @ohagi'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '0').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '0').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
status2 = subject.call(status, status.account_id, text: text)
|
status2 = subject.call(status, status.account_id, text: text)
|
||||||
|
|
||||||
|
@ -312,7 +314,8 @@ RSpec.describe UpdateStatusService do
|
||||||
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
mentioned.follow!(account)
|
mentioned.follow!(account)
|
||||||
text = 'ng word test @ohagi'
|
text = 'ng word test @ohagi'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
status2 = subject.call(status, status.account_id, text: text)
|
status2 = subject.call(status, status.account_id, text: text)
|
||||||
|
|
||||||
|
@ -322,7 +325,8 @@ RSpec.describe UpdateStatusService do
|
||||||
|
|
||||||
it 'hit ng words for reply' do
|
it 'hit ng words for reply' do
|
||||||
text = 'ng word test'
|
text = 'ng word test'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
status = PostStatusService.new.call(account, text: 'hello', thread: Fabricate(:status))
|
status = PostStatusService.new.call(account, text: 'hello', thread: Fabricate(:status))
|
||||||
|
|
||||||
|
@ -334,7 +338,8 @@ RSpec.describe UpdateStatusService do
|
||||||
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
||||||
mentioned.follow!(account)
|
mentioned.follow!(account)
|
||||||
text = 'ng word test'
|
text = 'ng word test'
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
status = PostStatusService.new.call(account, text: 'hello', thread: Fabricate(:status, account: mentioned))
|
status = PostStatusService.new.call(account, text: 'hello', thread: Fabricate(:status, account: mentioned))
|
||||||
|
|
||||||
|
@ -360,7 +365,8 @@ RSpec.describe UpdateStatusService do
|
||||||
it 'hit ng words for reference' do
|
it 'hit ng words for reference' do
|
||||||
target_status = Fabricate(:status)
|
target_status = Fabricate(:status)
|
||||||
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
status = PostStatusService.new.call(account, text: 'hello')
|
status = PostStatusService.new.call(account, text: 'hello')
|
||||||
|
|
||||||
|
@ -371,7 +377,8 @@ RSpec.describe UpdateStatusService do
|
||||||
target_status = Fabricate(:status)
|
target_status = Fabricate(:status)
|
||||||
target_status.account.follow!(status.account)
|
target_status.account.follow!(status.account)
|
||||||
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
|
||||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
Form::AdminSettings.new(stranger_mention_from_local_ng: '1').save
|
||||||
|
Fabricate(:ng_word, keyword: 'test')
|
||||||
|
|
||||||
status = PostStatusService.new.call(account, text: 'hello')
|
status = PostStatusService.new.call(account, text: 'hello')
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue