Deprecated (описывали состояние до рефакторинга): [DEPRECATED]-plan.md [DEPRECATED]-analysis-2026-05-30.md [DEPRECATED]-auth-architecture.md Новые/обновлённые: architecture.md — текущее устройство: стек, модули, auth-схема, env, маршруты plan.md — только pending задачи (блокеры KK, деплой, Redis, пагинация) questions.md — закрытые вопросы отмечены, открытые: KK creds + admin claim + /export IP
113 lines
6.5 KiB
Markdown
113 lines
6.5 KiB
Markdown
# Анализ проекта IP WhiteList — 30.05.2026
|
|
|
|
## Что сделано
|
|
|
|
| Компонент | Файл | Строк | Статус |
|
|
|---|---|---|---|
|
|
| Express-сервер, роуты | `server.js` | 101 | ✅ |
|
|
| Валидатор IPv4/CIDR | `src/validators.js` | 99 | ✅ |
|
|
| CRUD + audit_log | `src/queries.js` | 149 | ✅ |
|
|
| Пул PG | `src/db.js` | 24 | ✅ |
|
|
| UI (EJS, стиль Nubes) | `views/index.ejs` | 248 | ✅ |
|
|
| Схема БД | `sql/schema.sql` | 39 | ✅ |
|
|
| Favicon | `public/favicon.png` | — | ✅ |
|
|
| Дизайн-система (документ) | `docs/nubes-design-system.md` | — | ✅ |
|
|
| Тестирование | `tests/test-results.md` | 16/16 ✅ | ✅ |
|
|
|
|
### Валидатор — что проверяет:
|
|
- RFC1918 (10/8, 172.16/12, 192.168/16) — запрет
|
|
- TEST-NET (192.0.2/24, 198.51.100/24, 203.0.113/24) — запрет
|
|
- Loopback, link-local — запрет
|
|
- IPv6 — запрет
|
|
- Маска: допускается только /22–/32
|
|
- Нормализация host-битов (10.0.0.1/24 → 10.0.0.0/24)
|
|
- Пересечения с уже существующими записями — запрет
|
|
- Лимит записей на компанию (по умолчанию 15)
|
|
|
|
### Экспорт:
|
|
- `GET /export` → plain text, один CIDR на строку, без заголовков
|
|
|
|
---
|
|
|
|
## Что не готово (критично для продакшена)
|
|
|
|
### 1. JWT-авторизация
|
|
**Сейчас:** `DEV_MODE=true` — авторизация заглушена, `clientId` захардкожен.
|
|
**Нужно:** Распаковка JWT из `Authorization: Bearer <token>` → извлечение `clientId` и `email`.
|
|
Схема описана в `docs/auth-architecture.md`.
|
|
**Риск:** без этого нельзя открывать сервис для реальных пользователей — любой запрос видит и меняет все данные.
|
|
|
|
### 2. Изоляция данных по компании
|
|
**Сейчас:** Все роуты используют один захардкоженный `clientId`. БД правильная (таблица `companies` есть), но `WHERE company_id = $1` не работает по-настоящему без JWT.
|
|
**Нужно:** После JWT — всё заработает автоматически, код менять не придётся.
|
|
|
|
### 3. CSRF-защита на POST-формах
|
|
**Сейчас:** Формы без CSRF-токена.
|
|
**Нужно:** `csurf` middleware или `SameSite=Strict` на session cookie.
|
|
Или, если фронт перейдёт на fetch/JSON API — Authorization header автоматически решает проблему.
|
|
|
|
---
|
|
|
|
## Замечания и предложения
|
|
|
|
### Архитектура
|
|
|
|
- `server.js` содержит все роуты в одном файле (101 строка). Пока норм, но при добавлении админки/API станет неудобно. Рекомендую разбить на `routes/user.js`, `routes/admin.js`, `routes/api.js` перед тем как добавлять функциональность.
|
|
|
|
- `queries.js` возвращает сырые строки, не объекты с явным типом. Если сервис будет расти — стоит обернуть в Result-паттерн `{ ok, data, error }`.
|
|
|
|
### UI
|
|
|
|
- Нет пагинации. При лимите 15 записей на компанию — не критично. Если лимит поднимут до 100+ — нужна.
|
|
- Нет поиска/фильтрации в таблице.
|
|
- Алерты исчезают только при перезагрузке страницы (flash-сообщения). Если добавить JS — можно auto-dismiss через 5 секунд.
|
|
|
|
### Экспорт
|
|
|
|
- Сейчас `GET /export` отдаёт все CIDR без суммаризации. Если у компании 10 записей типа `1.2.3.0/28` и `1.2.3.16/28` — они будут двумя строками. Суммаризация в `/28` + `/28` → `/27` сократила бы файл и упростила настройку оборудования. Это отдельная задача, потребует библиотеку CIDR-merge.
|
|
|
|
### Тесты
|
|
|
|
- Тесты ручные (curl в md-файле). Для CI/CD нужен автоматический прогон: `jest` или `supertest`. Команда для инициализации: `npm install --save-dev jest supertest`.
|
|
|
|
### БД
|
|
|
|
- `audit_log` пишется, но нигде не отображается пользователю. Для полноты — стоит добавить вкладку "История" или endpoint `GET /audit`.
|
|
- Нет индекса на `whitelist_entries(company_id)` — при росте данных будет полный скан. Добавить в `schema.sql`:
|
|
```sql
|
|
CREATE INDEX idx_whitelist_company ON whitelist_entries(company_id);
|
|
CREATE INDEX idx_audit_company ON audit_log(company_id);
|
|
```
|
|
|
|
### Безопасность
|
|
|
|
- `.env` в `.gitignore` ✅ — правильно.
|
|
- `secrets.txt` в корне репо — нужно убедиться что он тоже в `.gitignore`.
|
|
- Параметризованные запросы в `queries.js` ✅ — SQL-инъекции закрыты.
|
|
- `express-validator` не подключён — валидация только на уровне `validators.js`. Нормально, т.к. все входные данные проходят через него.
|
|
|
|
---
|
|
|
|
## Приоритеты следующих задач
|
|
|
|
1. **JWT** — без этого продакшен не открыть
|
|
2. **CSRF** — параллельно с JWT
|
|
3. **Индексы БД** — 2 строки в schema.sql, риск нулевой
|
|
4. **Разбивка роутов** — перед добавлением админки
|
|
5. **Автотесты** — перед CI/CD
|
|
6. **Суммаризация CIDR** — nice to have
|
|
7. **Пагинация + фильтр** — после поднятия лимита
|
|
8. **Audit UI** — опционально
|
|
|
|
---
|
|
|
|
## Текущий стек
|
|
|
|
- Node.js + Express.js
|
|
- PostgreSQL (pg pool)
|
|
- EJS templates
|
|
- Платформа: Nubes NodeJS instance "white"
|
|
- URL: `https://white.nodejsk8s.dev.nubes.ru`
|
|
- Repo (код): `gitea.services.ngcloud.ru/Nail/ipwhitelist-app.git`
|
|
- Repo (docs): `gitea.services.ngcloud.ru/Nail/IPWhiteList.git`
|