This commit is contained in:
Professional 2025-05-25 22:43:02 +07:00
parent fc3ff065aa
commit 340fe8993c
2 changed files with 55 additions and 7 deletions

View File

@ -70,11 +70,27 @@ class ProfanityFilter {
*/
generateWordPatterns(words) {
this.wordPatterns = words
.filter(word => word && word.length >= 4) // Берем только слова длиннее 3 символов для производных
.filter(word => word && word.length >= 3) // Снижаем минимальную длину до 3 символов
.map(word => {
// Создаем шаблон для каждого слова: допускает изменение окончаний и вставку символов
const baseWord = word.replace(/[еёо]/g, '[еёо]'); // Учитываем замену е/ё/о
return new RegExp(`\\b${baseWord}[а-яёa-z]*\\b`, 'i');
// Создаем шаблон с учетом возможных разделителей и замен символов
const baseWord = word
.replace(/[еёо]/g, '[еёо]') // Учитываем замену е/ё/о
.replace(/а/g, '[аa@]') // Учитываем замену а на a латинскую или @
.replace(/о/g, '[оo0]') // Учитываем замену о на o латинскую или 0
.replace(/е/g, '[еe]') // Учитываем замену е на e латинскую
.replace(/с/g, '[сc]') // Учитываем замену с на c латинскую
.replace(/р/g, '[рp]') // Учитываем замену р на p латинскую
.replace(/х/g, '[хx]') // Учитываем замену х на x латинскую
.replace(/у/g, '[уy]') // Учитываем замену у на y латинскую
.replace(/и/g, '[иi]'); // Учитываем замену и на i
// Создаем регулярку, которая учитывает:
// - возможные разделители между буквами (точки, пробелы, дефисы)
// - возможные окончания слов
const chars = baseWord.split('');
const patternWithSeparators = chars.join('[\\s\\._\\-]*');
return new RegExp(`\\b${patternWithSeparators}[а-яёa-z]*\\b`, 'i');
});
}
@ -86,14 +102,17 @@ class ProfanityFilter {
hasProfanity(text) {
if (!text) return false;
// Нормализуем текст, убирая лишние символы и разделители
const normalizedText = text.toLowerCase()
.replace(/[\s\._\-]+/g, ''); // Удаляем пробелы, точки, подчеркивания, дефисы
// Проверяем сначала стандартным методом библиотеки bad-words
if (this.filter.isProfane(text.toLowerCase())) {
if (this.filter.isProfane(normalizedText) || this.filter.isProfane(text.toLowerCase())) {
return true;
}
// Дополнительная проверка на производные слова через регулярные выражения
const normalizedText = text.toLowerCase();
return this.wordPatterns.some(pattern => pattern.test(normalizedText));
return this.wordPatterns.some(pattern => pattern.test(text.toLowerCase()));
}
/**

View File

@ -173,6 +173,28 @@ import { ref, onMounted, onUnmounted, computed } from 'vue';
import { useAuth } from '@/auth';
import russianCities from '@/assets/russian-cities.json';
// Слова для базовой проверки на клиентской стороне
// (меньше, чем в полной библиотеке на сервере, но достаточно для основных случаев)
const badWords = [
'блядь', 'хуй', 'пизда', 'ебать', 'ебал', 'ебло', 'хуесос', 'пидор', 'пидорас',
'мудак', 'говно', 'залупа', 'хер', 'шлюха', 'соска', 'шалава', 'дебил', 'дрочить',
'сука', 'гандон', 'гондон'
];
// Функция для проверки на нецензурную лексику (упрощенная версия, основная проверка на сервере)
const hasProfanity = (text) => {
if (!text) return false;
const normalizedText = text.toLowerCase()
.replace(/[\s\._\-]+/g, '') // Удаляем пробелы, точки, подчеркивания, дефисы
.replace(/[еёo]/g, 'е') // Приводим похожие символы к общему виду
.replace(/[аa]/g, 'а')
.replace(/[оo0]/g, 'о');
// Проверяем на запрещенные слова
return badWords.some(word => normalizedText.includes(word.toLowerCase()));
};
const name = ref('');
const email = ref('');
const birthdate = ref('');
@ -271,6 +293,13 @@ const handleRegister = async () => {
return;
}
// Проверка имени на запрещенные слова
if (hasProfanity(name.value)) {
errorMessage.value = 'Имя содержит запрещенные слова или выражения. Пожалуйста, используйте другое имя.';
loading.value = false;
return;
}
try {
const userData = {
name: name.value,