ваше сообщение коммита
This commit is contained in:
@@ -45,7 +45,12 @@ async function ensureAdminPagesTable(fields) {
|
|||||||
'created_at TIMESTAMP DEFAULT NOW()',
|
'created_at TIMESTAMP DEFAULT NOW()',
|
||||||
'updated_at TIMESTAMP DEFAULT NOW()',
|
'updated_at TIMESTAMP DEFAULT NOW()',
|
||||||
'show_in_blog BOOLEAN DEFAULT FALSE', // Показывать в блоге
|
'show_in_blog BOOLEAN DEFAULT FALSE', // Показывать в блоге
|
||||||
'slug TEXT UNIQUE' // URL-friendly идентификатор для SEO
|
'slug TEXT UNIQUE', // URL-friendly идентификатор для SEO
|
||||||
|
'category_id INTEGER', // ID категории
|
||||||
|
'parent_id INTEGER', // ID родительской страницы
|
||||||
|
'order_index INTEGER DEFAULT 0', // Порядок сортировки
|
||||||
|
'nav_path TEXT', // Путь навигации
|
||||||
|
'is_index_page BOOLEAN DEFAULT FALSE' // Является ли индексной страницей
|
||||||
];
|
];
|
||||||
for (const field of fields) {
|
for (const field of fields) {
|
||||||
columns.push(`"${field}_encrypted" TEXT`);
|
columns.push(`"${field}_encrypted" TEXT`);
|
||||||
@@ -89,6 +94,41 @@ async function ensureAdminPagesTable(fields) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Добавляем поле category_id если его нет
|
||||||
|
if (!existingCols.includes('category_id')) {
|
||||||
|
await db.getQuery()(
|
||||||
|
`ALTER TABLE ${tableName} ADD COLUMN category_id INTEGER`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем поле parent_id если его нет
|
||||||
|
if (!existingCols.includes('parent_id')) {
|
||||||
|
await db.getQuery()(
|
||||||
|
`ALTER TABLE ${tableName} ADD COLUMN parent_id INTEGER`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем поле order_index если его нет
|
||||||
|
if (!existingCols.includes('order_index')) {
|
||||||
|
await db.getQuery()(
|
||||||
|
`ALTER TABLE ${tableName} ADD COLUMN order_index INTEGER DEFAULT 0`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем поле nav_path если его нет
|
||||||
|
if (!existingCols.includes('nav_path')) {
|
||||||
|
await db.getQuery()(
|
||||||
|
`ALTER TABLE ${tableName} ADD COLUMN nav_path TEXT`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем поле is_index_page если его нет
|
||||||
|
if (!existingCols.includes('is_index_page')) {
|
||||||
|
await db.getQuery()(
|
||||||
|
`ALTER TABLE ${tableName} ADD COLUMN is_index_page BOOLEAN DEFAULT FALSE`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
for (const field of fields) {
|
for (const field of fields) {
|
||||||
const encryptedField = `${field}_encrypted`;
|
const encryptedField = `${field}_encrypted`;
|
||||||
if (!existingCols.includes(encryptedField)) {
|
if (!existingCols.includes(encryptedField)) {
|
||||||
@@ -205,9 +245,25 @@ async function generateUniqueSlug(title, pageId, tableName) {
|
|||||||
return slug;
|
return slug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Middleware для условной обработки multer (только для multipart/form-data)
|
||||||
|
const conditionalUpload = (req, res, next) => {
|
||||||
|
const contentType = req.headers['content-type'] || '';
|
||||||
|
if (contentType.includes('multipart/form-data')) {
|
||||||
|
return upload.single('file')(req, res, next);
|
||||||
|
}
|
||||||
|
// Для JSON запросов пропускаем multer
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
// Создать страницу (только для админа)
|
// Создать страницу (только для админа)
|
||||||
router.post('/', upload.single('file'), async (req, res) => {
|
router.post('/', conditionalUpload, async (req, res) => {
|
||||||
console.log('[pages] POST /: Начало обработки запроса на создание страницы');
|
console.log('[pages] POST /: Начало обработки запроса на создание страницы');
|
||||||
|
console.log('[pages] POST /: Content-Type:', req.headers['content-type']);
|
||||||
|
console.log('[pages] POST /: req.body тип:', typeof req.body);
|
||||||
|
console.log('[pages] POST /: req.body ключи:', req.body ? Object.keys(req.body) : 'req.body пуст');
|
||||||
|
console.log('[pages] POST /: req.body содержимое:', JSON.stringify(req.body || {}, null, 2).substring(0, 500));
|
||||||
|
console.log('[pages] POST /: req.file:', req.file ? { name: req.file.originalname, size: req.file.size } : 'нет файла');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!req.session || !req.session.authenticated) {
|
if (!req.session || !req.session.authenticated) {
|
||||||
console.log('[pages] POST /: Ошибка аутентификации - сессия не найдена');
|
console.log('[pages] POST /: Ошибка аутентификации - сессия не найдена');
|
||||||
@@ -245,6 +301,15 @@ router.post('/', upload.single('file'), async (req, res) => {
|
|||||||
// Собираем данные страницы
|
// Собираем данные страницы
|
||||||
const bodyRaw = req.body || {};
|
const bodyRaw = req.body || {};
|
||||||
|
|
||||||
|
// Проверяем, что body не пустой
|
||||||
|
if (!bodyRaw || Object.keys(bodyRaw).length === 0) {
|
||||||
|
console.error('[pages] POST /: req.body пуст или не определен');
|
||||||
|
return res.status(400).json({
|
||||||
|
error: 'Отсутствуют данные страницы',
|
||||||
|
message: 'Тело запроса пустое. Проверьте Content-Type и формат данных.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Обрабатываем required_permission: если это пустая строка или 'null', устанавливаем null
|
// Обрабатываем required_permission: если это пустая строка или 'null', устанавливаем null
|
||||||
let requiredPermission = null;
|
let requiredPermission = null;
|
||||||
if (bodyRaw.required_permission) {
|
if (bodyRaw.required_permission) {
|
||||||
@@ -2056,7 +2121,7 @@ Disallow: /admin/
|
|||||||
Disallow: /content/create
|
Disallow: /content/create
|
||||||
Disallow: /content/edit
|
Disallow: /content/edit
|
||||||
|
|
||||||
Sitemap: ${baseUrl}/api/pages/public/sitemap.xml
|
Sitemap: ${baseUrl}/sitemap.xml
|
||||||
`;
|
`;
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'text/plain');
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ DLE is designed for **all types of organizations** that need transparent collect
|
|||||||
|
|
||||||
✅ **All licenses include:**
|
✅ **All licenses include:**
|
||||||
- Lifetime access to the application
|
- Lifetime access to the application
|
||||||
- All future updates free
|
- All future updates free for 5 years (for token holders)
|
||||||
|
- **Free setup by contractors within 5 years** (personalization for your business type, integration with business processes, AI assistant configuration, blockchain accounting setup, feature customization if needed)
|
||||||
- Technical support through portal
|
- Technical support through portal
|
||||||
- AI assistant 24/7 without limits
|
- AI assistant 24/7 without limits
|
||||||
- Participation in voting for new features
|
- Participation in voting for new features
|
||||||
@@ -104,6 +105,7 @@ DLE is designed for **all types of organizations** that need transparent collect
|
|||||||
- Pay once
|
- Pay once
|
||||||
- Access forever
|
- Access forever
|
||||||
- All updates free for 5 years for license token holders (see [legal/service-terms.md](../legal-en/service-terms.md))
|
- All updates free for 5 years for license token holders (see [legal/service-terms.md](../legal-en/service-terms.md))
|
||||||
|
- **Free setup by contractors within 5 years** after license purchase
|
||||||
- No hidden fees
|
- No hidden fees
|
||||||
- AI works without request limits
|
- AI works without request limits
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@ DLE is designed for **all types of organizations** that need transparent collect
|
|||||||
- 🎓 **Online training sessions** (group and individual)
|
- 🎓 **Online training sessions** (group and individual)
|
||||||
- 📚 **Library of recordings** of all sessions
|
- 📚 **Library of recordings** of all sessions
|
||||||
- 📧 **Email support**
|
- 📧 **Email support**
|
||||||
|
- ✅ **Free setup by contractors within 5 years** (personalization, integration, AI configuration, feature customization)
|
||||||
|
|
||||||
### How does the voting system work?
|
### How does the voting system work?
|
||||||
|
|
||||||
@@ -734,6 +737,7 @@ Always end with: "How else can I help? 😊"
|
|||||||
|
|
||||||
**All license holders receive**:
|
**All license holders receive**:
|
||||||
- ✅ All web application updates (free for 5 years for token holders)
|
- ✅ All web application updates (free for 5 years for token holders)
|
||||||
|
- ✅ **Free setup by contractors within 5 years** (personalization, integration, AI configuration, feature customization)
|
||||||
- ✅ Access to documentation and knowledge base
|
- ✅ Access to documentation and knowledge base
|
||||||
- ✅ Technical support through application
|
- ✅ Technical support through application
|
||||||
- ✅ AI assistant 24/7
|
- ✅ AI assistant 24/7
|
||||||
@@ -803,6 +807,7 @@ You can request refund of **70% of license cost** within **5 years** from purcha
|
|||||||
- 🎓 Online training sessions (all licenses)
|
- 🎓 Online training sessions (all licenses)
|
||||||
- 📚 Library of recordings (all licenses)
|
- 📚 Library of recordings (all licenses)
|
||||||
- 📧 Email support (all licenses)
|
- 📧 Email support (all licenses)
|
||||||
|
- ✅ Free setup by contractors within 5 years (all licenses)
|
||||||
|
|
||||||
**SLA (first response time)**:
|
**SLA (first response time)**:
|
||||||
- 🔴 Critical: 4 hours
|
- 🔴 Critical: 4 hours
|
||||||
@@ -994,7 +999,7 @@ curl -fsSL https://raw.githubusercontent.com/VC-HB3-Accelerator/DLE/main/setup-t
|
|||||||
**One-time costs**:
|
**One-time costs**:
|
||||||
- License: $1,000-10,000 USDT
|
- License: $1,000-10,000 USDT
|
||||||
- Smart contract deployment: $100-500 (gas fees)
|
- Smart contract deployment: $100-500 (gas fees)
|
||||||
- Setup: $0 (self-service)
|
- Setup: $0 (free setup by contractors within 5 years included in license)
|
||||||
|
|
||||||
**Monthly costs**:
|
**Monthly costs**:
|
||||||
- Hosting: $50-200/month
|
- Hosting: $50-200/month
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
Key Points:
|
Key Points:
|
||||||
- License Type: Perpetual, rights determined by number of tokens (1 or 10).
|
- License Type: Perpetual, rights determined by number of tokens (1 or 10).
|
||||||
- Updates and Basic Maintenance: Free for 5 years from on-chain token transfer date.
|
- Updates and Basic Maintenance: Free for 5 years from on-chain token transfer date.
|
||||||
|
- Free Setup by Contractors: Within 5 years after license purchase (personalization, integration, AI configuration, feature customization).
|
||||||
- Development Voting: 1 token = 1 vote, decisions by majority ≥51%.
|
- Development Voting: 1 token = 1 vote, decisions by majority ≥51%.
|
||||||
- 70% Refund possible if program conditions are met (see original).
|
- 70% Refund possible if program conditions are met (see original).
|
||||||
- Support, releases, knowledge base — through application `https://hb3-accelerator.com/`.
|
- Support, releases, knowledge base — through application `https://hb3-accelerator.com/`.
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ DLE создано для **всех типов организаций**, нуж
|
|||||||
|
|
||||||
✅ **Все лицензии включают:**
|
✅ **Все лицензии включают:**
|
||||||
- Пожизненный доступ к приложению
|
- Пожизненный доступ к приложению
|
||||||
- Все будущие обновления бесплатно
|
- Все будущие обновления бесплатно 5 лет (для держателей токенов)
|
||||||
|
- **Бесплатная настройка подрядчиками в течение 5 лет** (персонализация под ваш вид деятельности, интеграция с бизнес-процессами, настройка ИИ-ассистента, настройка блокчейн-учёта, доработка функционала при необходимости)
|
||||||
- Техническую поддержку через портал
|
- Техническую поддержку через портал
|
||||||
- AI ассистент 24/7 без лимитов
|
- AI ассистент 24/7 без лимитов
|
||||||
- Участие в голосовании за новые функции
|
- Участие в голосовании за новые функции
|
||||||
@@ -104,6 +105,7 @@ DLE создано для **всех типов организаций**, нуж
|
|||||||
- Оплата один раз
|
- Оплата один раз
|
||||||
- Доступ навсегда
|
- Доступ навсегда
|
||||||
- Все обновления бесплатно 5 лет для держателей лицензионных токенов (см. [legal/service-terms.md](../legal/service-terms.md))
|
- Все обновления бесплатно 5 лет для держателей лицензионных токенов (см. [legal/service-terms.md](../legal/service-terms.md))
|
||||||
|
- **Бесплатная настройка подрядчиками в течение 5 лет** после покупки лицензии
|
||||||
- Никаких скрытых платежей
|
- Никаких скрытых платежей
|
||||||
- AI работает без лимитов на запросы
|
- AI работает без лимитов на запросы
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@ DLE создано для **всех типов организаций**, нуж
|
|||||||
- 🎓 **Онлайн-сессии обучения** (групповые и индивидуальные)
|
- 🎓 **Онлайн-сессии обучения** (групповые и индивидуальные)
|
||||||
- 📚 **Библиотека записей** всех сессий
|
- 📚 **Библиотека записей** всех сессий
|
||||||
- 📧 **Email поддержка**
|
- 📧 **Email поддержка**
|
||||||
|
- ✅ **Бесплатная настройка подрядчиками в течение 5 лет** (персонализация, интеграция, настройка ИИ, доработка функционала)
|
||||||
|
|
||||||
### Как работает система голосования?
|
### Как работает система голосования?
|
||||||
|
|
||||||
@@ -734,6 +737,7 @@ DLE создано для **всех типов организаций**, нуж
|
|||||||
|
|
||||||
**Все держатели лицензий получают**:
|
**Все держатели лицензий получают**:
|
||||||
- ✅ Все обновления веб-приложения (бесплатно 5 лет для держателей токенов)
|
- ✅ Все обновления веб-приложения (бесплатно 5 лет для держателей токенов)
|
||||||
|
- ✅ **Бесплатная настройка подрядчиками в течение 5 лет** (персонализация, интеграция, настройка ИИ, доработка функционала)
|
||||||
- ✅ Доступ к документации и базе знаний
|
- ✅ Доступ к документации и базе знаний
|
||||||
- ✅ Техническая поддержка через приложение
|
- ✅ Техническая поддержка через приложение
|
||||||
- ✅ AI ассистент 24/7
|
- ✅ AI ассистент 24/7
|
||||||
@@ -803,6 +807,7 @@ DLE создано для **всех типов организаций**, нуж
|
|||||||
- 🎓 Онлайн-сессии обучения (все лицензии)
|
- 🎓 Онлайн-сессии обучения (все лицензии)
|
||||||
- 📚 Библиотека записей (все лицензии)
|
- 📚 Библиотека записей (все лицензии)
|
||||||
- 📧 Email поддержка (все лицензии)
|
- 📧 Email поддержка (все лицензии)
|
||||||
|
- ✅ Бесплатная настройка подрядчиками в течение 5 лет (все лицензии)
|
||||||
|
|
||||||
**SLA (время первого ответа)**:
|
**SLA (время первого ответа)**:
|
||||||
- 🔴 Критическая: 4 часа
|
- 🔴 Критическая: 4 часа
|
||||||
@@ -994,7 +999,7 @@ curl -fsSL https://raw.githubusercontent.com/VC-HB3-Accelerator/DLE/main/setup-t
|
|||||||
**Единоразовые расходы**:
|
**Единоразовые расходы**:
|
||||||
- Лицензия: $1,000-10,000 USDT
|
- Лицензия: $1,000-10,000 USDT
|
||||||
- Деплой смарт-контракта: $100-500 (gas fees)
|
- Деплой смарт-контракта: $100-500 (gas fees)
|
||||||
- Настройка: $0 (самостоятельно)
|
- Настройка: $0 (бесплатная настройка подрядчиками в течение 5 лет включена в лицензию)
|
||||||
|
|
||||||
**Ежемесячные расходы**:
|
**Ежемесячные расходы**:
|
||||||
- Хостинг: $50-200/месяц
|
- Хостинг: $50-200/месяц
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
Ключевые тезисы:
|
Ключевые тезисы:
|
||||||
- Тип лицензии: бессрочная (Perpetual), права определяются количеством токенов (1 или 10).
|
- Тип лицензии: бессрочная (Perpetual), права определяются количеством токенов (1 или 10).
|
||||||
- Обновления и базовое обслуживание: бесплатно 5 лет с даты on-chain передачи токена.
|
- Обновления и базовое обслуживание: бесплатно 5 лет с даты on-chain передачи токена.
|
||||||
|
- Бесплатная настройка подрядчиками: в течение 5 лет после покупки лицензии (персонализация, интеграция, настройка ИИ, доработка функционала).
|
||||||
- Голосование за развитие: 1 токен = 1 голос, решения большинством ≥51%.
|
- Голосование за развитие: 1 токен = 1 голос, решения большинством ≥51%.
|
||||||
- Возврат 70% возможен при соблюдении условий программы (см. оригинал).
|
- Возврат 70% возможен при соблюдении условий программы (см. оригинал).
|
||||||
- Поддержка, релизы, база знаний — через приложение `https://hb3-accelerator.com/`.
|
- Поддержка, релизы, база знаний — через приложение `https://hb3-accelerator.com/`.
|
||||||
|
|||||||
@@ -28,6 +28,25 @@ http {
|
|||||||
add_header Content-Type text/plain;
|
add_header Content-Type text/plain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем
|
||||||
|
location = /robots.txt {
|
||||||
|
proxy_pass http://${BACKEND_CONTAINER}:8000/api/pages/public/robots.txt;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /sitemap.xml {
|
||||||
|
proxy_pass http://${BACKEND_CONTAINER}:8000/api/pages/public/sitemap.xml;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type application/xml;
|
||||||
|
}
|
||||||
|
|
||||||
# Основной location
|
# Основной location
|
||||||
location / {
|
location / {
|
||||||
# Rate limiting для основных страниц (отключено)
|
# Rate limiting для основных страниц (отключено)
|
||||||
|
|||||||
@@ -13,13 +13,21 @@ http {
|
|||||||
# limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
# limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
||||||
# limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=5r/s;
|
# limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=5r/s;
|
||||||
|
|
||||||
# Блокировка известных сканеров и вредоносных ботов
|
# Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты)
|
||||||
map $http_user_agent $bad_bot {
|
map $http_user_agent $bad_bot {
|
||||||
default 0;
|
default 0;
|
||||||
~*bot 1;
|
# Разрешаем легитимные поисковые боты
|
||||||
~*crawler 1;
|
~*googlebot 0;
|
||||||
~*spider 1;
|
~*bingbot 0;
|
||||||
~*scanner 1;
|
~*slurp 0;
|
||||||
|
~*duckduckbot 0;
|
||||||
|
~*baiduspider 0;
|
||||||
|
~*yandex 0;
|
||||||
|
~*sogou 0;
|
||||||
|
~*exabot 0;
|
||||||
|
~*facebot 0;
|
||||||
|
~*ia_archiver 0;
|
||||||
|
# Блокируем вредоносные боты и сканеры
|
||||||
~*sqlmap 1;
|
~*sqlmap 1;
|
||||||
~*nikto 1;
|
~*nikto 1;
|
||||||
~*dirb 1;
|
~*dirb 1;
|
||||||
@@ -29,6 +37,9 @@ http {
|
|||||||
~*zap 1;
|
~*zap 1;
|
||||||
~*nessus 1;
|
~*nessus 1;
|
||||||
~*openvas 1;
|
~*openvas 1;
|
||||||
|
~*masscan 1;
|
||||||
|
~*nmap 1;
|
||||||
|
~*scanner 1;
|
||||||
~*Chrome/[1-4][0-9]\. 1;
|
~*Chrome/[1-4][0-9]\. 1;
|
||||||
~*Firefox/[1-6][0-9]\. 1;
|
~*Firefox/[1-6][0-9]\. 1;
|
||||||
~*Safari/[1-9]\. 1;
|
~*Safari/[1-9]\. 1;
|
||||||
|
|||||||
@@ -37,13 +37,21 @@ function getNginxConfig(domain, serverPort) {
|
|||||||
# limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
# limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
||||||
# limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=50r/s;
|
# limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=50r/s;
|
||||||
|
|
||||||
# Блокировка известных сканеров и вредоносных ботов
|
# Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты)
|
||||||
map $http_user_agent $bad_bot {
|
map $http_user_agent $bad_bot {
|
||||||
default 0;
|
default 0;
|
||||||
~*bot 1;
|
# Разрешаем легитимные поисковые боты
|
||||||
~*crawler 1;
|
~*googlebot 0;
|
||||||
~*spider 1;
|
~*bingbot 0;
|
||||||
~*scanner 1;
|
~*slurp 0;
|
||||||
|
~*duckduckbot 0;
|
||||||
|
~*baiduspider 0;
|
||||||
|
~*yandex 0;
|
||||||
|
~*sogou 0;
|
||||||
|
~*exabot 0;
|
||||||
|
~*facebot 0;
|
||||||
|
~*ia_archiver 0;
|
||||||
|
# Блокируем вредоносные боты и сканеры
|
||||||
~*sqlmap 1;
|
~*sqlmap 1;
|
||||||
~*nikto 1;
|
~*nikto 1;
|
||||||
~*dirb 1;
|
~*dirb 1;
|
||||||
@@ -53,6 +61,9 @@ map $http_user_agent $bad_bot {
|
|||||||
~*zap 1;
|
~*zap 1;
|
||||||
~*nessus 1;
|
~*nessus 1;
|
||||||
~*openvas 1;
|
~*openvas 1;
|
||||||
|
~*masscan 1;
|
||||||
|
~*nmap 1;
|
||||||
|
~*scanner 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
@@ -74,12 +85,31 @@ server {
|
|||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Защита от доступа к чувствительным файлам
|
# Защита от доступа к чувствительным файлам (исключаем robots.txt и sitemap.xml для SEO)
|
||||||
location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config|robots\\\\.txt|sitemap\\\\.xml)$ {
|
location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config)$ {
|
||||||
deny all;
|
deny all;
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем
|
||||||
|
location = /robots.txt {
|
||||||
|
proxy_pass http://localhost:8000/api/pages/public/robots.txt;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /sitemap.xml {
|
||||||
|
proxy_pass http://localhost:8000/api/pages/public/sitemap.xml;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type application/xml;
|
||||||
|
}
|
||||||
|
|
||||||
# Основной location для фронтенда
|
# Основной location для фронтенда
|
||||||
location / {
|
location / {
|
||||||
# Rate limiting для основных страниц (отключено)
|
# Rate limiting для основных страниц (отключено)
|
||||||
@@ -476,13 +506,21 @@ app.post('/tunnel/create', async (req, res) => {
|
|||||||
# limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
# limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
||||||
# limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=50r/s;
|
# limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=50r/s;
|
||||||
|
|
||||||
# Блокировка известных сканеров и вредоносных ботов
|
# Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты)
|
||||||
map $http_user_agent $bad_bot {
|
map $http_user_agent $bad_bot {
|
||||||
default 0;
|
default 0;
|
||||||
~*bot 1;
|
# Разрешаем легитимные поисковые боты
|
||||||
~*crawler 1;
|
~*googlebot 0;
|
||||||
~*spider 1;
|
~*bingbot 0;
|
||||||
~*scanner 1;
|
~*slurp 0;
|
||||||
|
~*duckduckbot 0;
|
||||||
|
~*baiduspider 0;
|
||||||
|
~*yandex 0;
|
||||||
|
~*sogou 0;
|
||||||
|
~*exabot 0;
|
||||||
|
~*facebot 0;
|
||||||
|
~*ia_archiver 0;
|
||||||
|
# Блокируем вредоносные боты и сканеры
|
||||||
~*sqlmap 1;
|
~*sqlmap 1;
|
||||||
~*nikto 1;
|
~*nikto 1;
|
||||||
~*dirb 1;
|
~*dirb 1;
|
||||||
@@ -492,6 +530,9 @@ map $http_user_agent $bad_bot {
|
|||||||
~*zap 1;
|
~*zap 1;
|
||||||
~*nessus 1;
|
~*nessus 1;
|
||||||
~*openvas 1;
|
~*openvas 1;
|
||||||
|
~*masscan 1;
|
||||||
|
~*nmap 1;
|
||||||
|
~*scanner 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
@@ -513,12 +554,31 @@ server {
|
|||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Защита от доступа к чувствительным файлам
|
# Защита от доступа к чувствительным файлам (исключаем robots.txt и sitemap.xml для SEO)
|
||||||
location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config|robots\\\\.txt|sitemap\\\\.xml)$ {
|
location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config)$ {
|
||||||
deny all;
|
deny all;
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем
|
||||||
|
location = /robots.txt {
|
||||||
|
proxy_pass http://localhost:8000/api/pages/public/robots.txt;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /sitemap.xml {
|
||||||
|
proxy_pass http://localhost:8000/api/pages/public/sitemap.xml;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type application/xml;
|
||||||
|
}
|
||||||
|
|
||||||
# Основной location для фронтенда
|
# Основной location для фронтенда
|
||||||
location / {
|
location / {
|
||||||
# Rate limiting для основных страниц (отключено)
|
# Rate limiting для основных страниц (отключено)
|
||||||
|
|||||||
@@ -190,3 +190,4 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,15 @@ NC='\033[0m' # No Color
|
|||||||
echo -e "${GREEN}🔄 Синхронизация кода с VDS...${NC}"
|
echo -e "${GREEN}🔄 Синхронизация кода с VDS...${NC}"
|
||||||
|
|
||||||
# Параметры VDS (из настроек)
|
# Параметры VDS (из настроек)
|
||||||
VDS_HOST="185.26.121.127"
|
VDS_HOST="185.221.214.140"
|
||||||
VDS_USER="root"
|
VDS_USER="root"
|
||||||
VDS_PORT="22"
|
VDS_PORT="22"
|
||||||
VDS_PATH="/home/docker/dapp"
|
VDS_PATH="/home/docker/dapp"
|
||||||
|
|
||||||
# SSH опции
|
# SSH опции
|
||||||
SSH_OPTS="-p $VDS_PORT -o StrictHostKeyChecking=no"
|
SSH_OPTS="-p $VDS_PORT -o StrictHostKeyChecking=no"
|
||||||
|
# SCP опции (scp использует -P для порта, а не -p)
|
||||||
|
SCP_OPTS="-P $VDS_PORT -o StrictHostKeyChecking=no"
|
||||||
|
|
||||||
# Проверяем наличие rsync на удаленном сервере
|
# Проверяем наличие rsync на удаленном сервере
|
||||||
echo -e "${YELLOW}🔍 Проверка наличия rsync на VDS...${NC}"
|
echo -e "${YELLOW}🔍 Проверка наличия rsync на VDS...${NC}"
|
||||||
@@ -94,7 +96,7 @@ sync_with_tar() {
|
|||||||
-C "$(dirname "$SRC_DIR")" "$DIR_NAME"
|
-C "$(dirname "$SRC_DIR")" "$DIR_NAME"
|
||||||
|
|
||||||
# Копируем архив на VDS
|
# Копируем архив на VDS
|
||||||
scp -e "ssh $SSH_OPTS" "$TMP_TAR" "$VDS_USER@$VDS_HOST:/tmp/"
|
scp $SCP_OPTS "$TMP_TAR" "$VDS_USER@$VDS_HOST:/tmp/"
|
||||||
|
|
||||||
# Распаковываем на VDS
|
# Распаковываем на VDS
|
||||||
ssh $SSH_OPTS $VDS_USER@$VDS_HOST "mkdir -p $DST_DIR && tar -xzf /tmp/$(basename $TMP_TAR) -C $DST_DIR --strip-components=1 && rm /tmp/$(basename $TMP_TAR)"
|
ssh $SSH_OPTS $VDS_USER@$VDS_HOST "mkdir -p $DST_DIR && tar -xzf /tmp/$(basename $TMP_TAR) -C $DST_DIR --strip-components=1 && rm /tmp/$(basename $TMP_TAR)"
|
||||||
@@ -129,13 +131,13 @@ fi
|
|||||||
|
|
||||||
# Синхронизация docker-compose.prod.yml
|
# Синхронизация docker-compose.prod.yml
|
||||||
echo -e "${YELLOW}📦 Синхронизация docker-compose.prod.yml...${NC}"
|
echo -e "${YELLOW}📦 Синхронизация docker-compose.prod.yml...${NC}"
|
||||||
scp -e "ssh $SSH_OPTS" ./webssh-agent/docker-compose.prod.yml "$VDS_USER@$VDS_HOST:$VDS_PATH/docker-compose.prod.yml"
|
scp $SCP_OPTS ./webssh-agent/docker-compose.prod.yml "$VDS_USER@$VDS_HOST:$VDS_PATH/docker-compose.prod.yml"
|
||||||
|
|
||||||
# Синхронизация Dockerfile файлов (если они изменились)
|
# Синхронизация Dockerfile файлов (если они изменились)
|
||||||
echo -e "${YELLOW}📦 Синхронизация Dockerfile файлов...${NC}"
|
echo -e "${YELLOW}📦 Синхронизация Dockerfile файлов...${NC}"
|
||||||
scp -e "ssh $SSH_OPTS" ./backend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/backend/Dockerfile" 2>/dev/null || true
|
scp $SCP_OPTS ./backend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/backend/Dockerfile" 2>/dev/null || true
|
||||||
scp -e "ssh $SSH_OPTS" ./frontend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/Dockerfile" 2>/dev/null || true
|
scp $SCP_OPTS ./frontend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/Dockerfile" 2>/dev/null || true
|
||||||
scp -e "ssh $SSH_OPTS" ./frontend/nginx.Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/nginx.Dockerfile" 2>/dev/null || true
|
scp $SCP_OPTS ./frontend/nginx.Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/nginx.Dockerfile" 2>/dev/null || true
|
||||||
|
|
||||||
echo -e "${GREEN}✅ Синхронизация завершена!${NC}"
|
echo -e "${GREEN}✅ Синхронизация завершена!${NC}"
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,21 @@ http {
|
|||||||
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
|
||||||
limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=5r/s;
|
limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=5r/s;
|
||||||
|
|
||||||
# Блокировка известных сканеров и вредоносных ботов
|
# Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты)
|
||||||
map $http_user_agent $bad_bot {
|
map $http_user_agent $bad_bot {
|
||||||
default 0;
|
default 0;
|
||||||
~*bot 1;
|
# Разрешаем легитимные поисковые боты
|
||||||
~*crawler 1;
|
~*googlebot 0;
|
||||||
~*spider 1;
|
~*bingbot 0;
|
||||||
~*scanner 1;
|
~*slurp 0;
|
||||||
|
~*duckduckbot 0;
|
||||||
|
~*baiduspider 0;
|
||||||
|
~*yandex 0;
|
||||||
|
~*sogou 0;
|
||||||
|
~*exabot 0;
|
||||||
|
~*facebot 0;
|
||||||
|
~*ia_archiver 0;
|
||||||
|
# Блокируем вредоносные боты и сканеры
|
||||||
~*sqlmap 1;
|
~*sqlmap 1;
|
||||||
~*nikto 1;
|
~*nikto 1;
|
||||||
~*dirb 1;
|
~*dirb 1;
|
||||||
@@ -26,6 +34,9 @@ http {
|
|||||||
~*zap 1;
|
~*zap 1;
|
||||||
~*nessus 1;
|
~*nessus 1;
|
||||||
~*openvas 1;
|
~*openvas 1;
|
||||||
|
~*masscan 1;
|
||||||
|
~*nmap 1;
|
||||||
|
~*scanner 1;
|
||||||
~*Chrome/[1-4][0-9]\. 1;
|
~*Chrome/[1-4][0-9]\. 1;
|
||||||
~*Firefox/[1-6][0-9]\. 1;
|
~*Firefox/[1-6][0-9]\. 1;
|
||||||
~*Safari/[1-9]\. 1;
|
~*Safari/[1-9]\. 1;
|
||||||
@@ -54,12 +65,31 @@ http {
|
|||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Защита от доступа к чувствительным файлам
|
# Защита от доступа к чувствительным файлам (исключаем robots.txt и sitemap.xml для SEO)
|
||||||
location ~* /(\.htaccess|\.htpasswd|\.env|\.git|\.svn|\.DS_Store|Thumbs\.db|web\.config|robots\.txt|sitemap\.xml)$ {
|
location ~* /(\.htaccess|\.htpasswd|\.env|\.git|\.svn|\.DS_Store|Thumbs\.db|web\.config)$ {
|
||||||
deny all;
|
deny all;
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем
|
||||||
|
location = /robots.txt {
|
||||||
|
proxy_pass http://BACKEND_CONTAINER_PLACEHOLDER:8000/api/pages/public/robots.txt;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /sitemap.xml {
|
||||||
|
proxy_pass http://BACKEND_CONTAINER_PLACEHOLDER:8000/api/pages/public/sitemap.xml;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Content-Type application/xml;
|
||||||
|
}
|
||||||
|
|
||||||
# Защита от доступа к конфигурационным файлам
|
# Защита от доступа к конфигурационным файлам
|
||||||
location ~* /\.(env|config|ini|conf|cfg|yml|yaml|json|xml|sql|db|bak|backup|old|tmp|temp|log)$ {
|
location ~* /\.(env|config|ini|conf|cfg|yml|yaml|json|xml|sql|db|bak|backup|old|tmp|temp|log)$ {
|
||||||
deny all;
|
deny all;
|
||||||
|
|||||||
Reference in New Issue
Block a user