fix: гонки (транзакции), валидатор (суперсеть, parseInt, слэши), auth (401, DEV_MODE, export), схема (UNIQUE, CHECK, FK), client-валидация

This commit is contained in:
2026-05-30 08:28:21 +03:00
parent 60972169c5
commit 51f2f4ddaf
5 changed files with 164 additions and 108 deletions
+15 -4
View File
@@ -32,13 +32,23 @@ function validate(input) {
if (/[a-zA-Z]/.test(raw.replace(/\./g, '').replace(/\//g, '').replace(/\d/g, '')))
throw new Error('Некорректный формат');
// Отсекаем множественные слэши
if ((raw.match(/\//g) || []).length > 1) {
throw new Error('Некорректный формат');
}
// Если нет маски — добавляем /32
let cidr = raw.includes('/') ? raw : raw + '/32';
const [addr, maskStr] = cidr.split('/');
// Строгая проверка маски (parseInt глотает мусор: '24abc' → 24)
if (!/^\d{1,2}$/.test(maskStr)) {
throw new Error('Некорректная маска');
}
const mask = parseInt(maskStr, 10);
if (isNaN(mask) || mask < 22 || mask > 32) {
if (mask < 22 || mask > 32) {
throw new Error('Маска должна быть от /22 до /32');
}
@@ -58,10 +68,11 @@ function validate(input) {
const wasNormalized = addr !== networkAddr;
const normalized = networkAddr + '/' + mask;
// Проверка запрещённых диапазонов
// Проверка запрещённых диапазонов (overlaps ловит оба направления:
// и запись внутри запрещённого блока, и суперсеть над ним)
for (const blocked of BLOCKED_RANGES) {
if (isSubnetOf(normalized, blocked)) {
throw new Error(`Диапазон ${normalized} запрещён (${blocked})`);
if (overlaps(normalized, blocked)) {
throw new Error(`Диапазон ${normalized} пересекается с запрещённым (${blocked})`);
}
}