Reflex/backend/utils/profanityFilter.js
2025-05-26 01:28:53 +07:00

100 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Утилита для фильтрации нежелательного контента
const fs = require('fs');
const path = require('path');
let filterPromise;
// Списки пользовательских слов (из ранее прочитанной версии файла)
const russianBadWords = [
'блядь', 'хуй', 'пизда', 'ебать', 'ебал', 'ебло', 'хуесос', 'пидор', 'пидорас',
'мудак', 'говно', 'залупа', 'хер', 'манда', 'спермоед', 'шлюха', 'соска', 'шалава',
'дебил', 'дрочить', 'дрочка', 'ебанутый', 'выродок', 'шмара', 'сука', 'членосос',
'гандон', 'гондон', 'гнида', 'вагина', 'хуи', 'жопа', 'шлюхи', 'проститутка'
];
const datingAppBadWords = [
'проститутка', 'интим', 'секс за деньги', 'эскорт', 'интим услуги',
'заплачу', 'заплати', 'минет', 'массаж с интимом'
];
function loadBadWordsFromFile(filePath) {
try {
if (fs.existsSync(filePath)) {
const content = fs.readFileSync(filePath, 'utf8');
const words = content.split('\\n') // Используем \\n как разделитель строк
.map(word => word.trim())
.filter(word => word && !word.startsWith('//') && word.length >= 3);
console.log(`Загружено ${words.length} запрещенных слов из файла ${filePath}`);
return words;
}
} catch (error) {
console.error(`Ошибка при загрузке слов из файла ${filePath}:`, error.message);
}
return [];
}
function getInitializedFilter() {
if (!filterPromise) {
filterPromise = import('bad-words').then(async BadWordsModule => {
const FilterConstructor = BadWordsModule.default || BadWordsModule; // .default часто используется для ESM default export
const instance = new FilterConstructor();
console.log('Фильтр bad-words успешно инициализирован.');
// Загрузка и добавление пользовательских слов
const wordsPath = path.join(__dirname, 'words.txt');
const enWordsPath = path.join(__dirname, 'en.txt');
const russianFileWords = loadBadWordsFromFile(wordsPath);
const englishFileWords = loadBadWordsFromFile(enWordsPath);
const allCustomWords = [
...russianBadWords,
...datingAppBadWords,
...russianFileWords,
...englishFileWords
].filter(word => typeof word === 'string' && word.length > 0);
if (allCustomWords.length > 0) {
instance.addWords(...allCustomWords);
console.log(`Добавлено ${allCustomWords.length} пользовательских слов в фильтр bad-words.`);
} else {
console.log('Пользовательские слова для добавления в фильтр bad-words не найдены.');
}
return instance;
}).catch(err => {
console.error("Критическая ошибка: не удалось загрузить или инициализировать модуль bad-words:", err);
// Возвращаем "заглушку" фильтра, чтобы приложение не падало
return {
isProfane: (text) => { console.warn("Фильтр bad-words недоступен, проверка isProfane пропущена."); return false; },
clean: (text) => { console.warn("Фильтр bad-words недоступен, операция clean пропущена."); return text; }
};
});
}
return filterPromise;
}
// Экспортируем объект с асинхронными функциями, которые используют инициализированный фильтр
module.exports = {
isProfane: async (text) => {
// Добавляем проверку, что text является строкой и не пустой
if (typeof text !== 'string' || text.trim() === '') return false;
const filter = await getInitializedFilter();
return filter.isProfane(text);
},
clean: async (text) => {
if (typeof text !== 'string') return ''; // Возвращаем пустую строку, если text не строка
const filter = await getInitializedFilter();
return filter.clean(text);
},
validateObject: async (obj, fields) => {
const filter = await getInitializedFilter();
for (const field of fields) {
if (obj && typeof obj[field] === 'string') { // Проверяем, что obj существует и obj[field] является строкой
if (filter.isProfane(obj[field])) {
return { isProfane: true, field };
}
}
}
return { isProfane: false, field: null };
}
};