Files
ipwhitelist-app/docs/STATE-old.md
T

9.3 KiB
Raw Blame History

Состояние проекта на 2026-05-30 14:43 (ветка sonnet)

Репозитории

Репо URL Ветка Локальный путь
Код приложения https://gitea.services.ngcloud.ru/Nail/ipwhitelist-app.git sonnet /home/naeel/ipwhitelist-app
Документация https://gitea.services.ngcloud.ru/Nail/IPWhiteList.git main /home/naeel/IPWhiteList

Стек

Node.js + Express + EJS + PostgreSQL + pg pool + jsonwebtoken

Деплой

  • URL: https://white.nodejsk8s.dev.nubes.ru
  • DEV_MODE=true (мок-аутентификация)
  • ⚠️ Нужен передеплой Nubes для ветки sonnet

БД

  • write.bde8229b-1381-4330-b24b-727ad73fcb44.dev.nubes.ru
  • user: super, db: ipwhitelist
  • Миграция от 2026-05-30 применена (CHECK, UNIQUE, индексы)

Что сделано в ветке sonnet (4 коммита поверх master)

1. src/validators.js — CIDR агрегация

  • aggregateCIDRs(cidrs) — суммаризация: merge пересекающихся + смежных диапазонов → минимальный набор CIDR
  • Вспомогательные: numToIP(n), rangeToCIDRs(start, end)
  • Экспортируется и используется в /export

2. src/auth.js — admin-роль

  • ADMIN_CLIENT_ID = process.env.ADMIN_CLIENT_ID || 'WZ01112'
  • req.user.isAdmin — определяется по clientId === ADMIN_CLIENT_ID
  • DEV_ADMIN=true в .env → admin-права в dev-режиме
  • requireAdmin middleware — 403 для не-admin

3. src/queries.js — новые функции

  • getCompanyById(id) — компания по числовому PK
  • getAllCompanies() — все компании + active_count (LEFT JOIN)
  • setLimit(companyId, newLimit) — установить/сбросить (null) индивидуальный лимит
  • getAudit() — обновлён: JOIN с companies (поля company_name, client_id)

4. server.js — новые роуты

  • /export — публичный (до auth.middleware), возвращает агрегированный список всех компаний
  • GET / — admin: видит все компании с переключателем ?company=X
  • POST /edit/:id — редактирование записи (admin + user)
  • GET /audit — журнал аудита (только admin)
  • GET /admin — управление лимитами (только admin)
  • POST /admin/limit/:companyId — изменить/сбросить лимит компании
  • backUrl() — хелпер для редиректа обратно с учётом контекста admin/user

5. views/index.ejs

  • Admin-панель выбора компании (dropdown + быстрые ссылки на Аудит/Лимиты)
  • Кнопки Аудит/Лимиты/Выйти в header для admin
  • Кнопка "Изменить" в таблице (открывает edit modal)
  • Edit modal — overlay с формой, закрывается по Escape/backdrop
  • Скрытый company_id в формах add/delete для корректной admin-ветки

6. views/audit.ejsновый

  • Таблица журнала аудита с фильтром по компании
  • Цветные badges (CREATE/UPDATE/DELETE)
  • old_value → new_value стрелочкой

7. views/admin.ejsновый

  • Таблица всех компаний: client_id, active_count, лимит
  • Прогресс-бар использования (зелёный/янтарный/красный)
  • Форма изменения лимита с подтверждением; кнопка ↺ сброс на дефолт

Не сделано (production-hardening, не баги)

  • helmet (X-Frame-Options, CSP, HSTS)
  • rate-limit на POST /add, /delete, /export
  • CSRF-токены в формах
  • JWT-верификация через внешний JWKS (нужен URL от девопсов)
  • Multi-company (нужен формат claims от платформы — массив clientId?)

Мёртвый код (не критично)

  • isSubnetOf() в validators.js — определена, не используется, не экспортируется

Для прода

Выставить в .env:

NODE_ENV=production
JWKS_URL=<auth-api JWKS URL>
ADMIN_CLIENT_ID=<clientId администратора>
DEFAULT_LIMIT=15

Репозитории

Репо URL Ветка Локальный путь
Код приложения https://gitea.services.ngcloud.ru/Nail/ipwhitelist-app.git master /home/naeel/ipwhitelist-app
Документация https://gitea.services.ngcloud.ru/Nail/IPWhiteList.git main /home/naeel/IPWhiteList

Стек

Node.js + Express + EJS + PostgreSQL + pg pool + jsonwebtoken

Деплой

  • URL: https://white.nodejsk8s.dev.nubes.ru
  • DEV_MODE=true (мок-аутентификация)
  • ⚠️ Код запушен, но Nubes не передеплоил — крутится старая версия

БД

  • write.bde8229b-1381-4330-b24b-727ad73fcb44.dev.nubes.ru
  • user: super, db: ipwhitelist
  • Миграция от 2026-05-30 применена (CHECK, UNIQUE, индексы)

Что сделано (запушено)

1. src/validators.js — исправлены 3 бага

  • Запрещённые диапазоны: isSubnetOfoverlaps (обход через суперсеть /22)
  • Маска: parseInt('24abc') глотал мусор → строгая проверка /^\d{1,2}$/
  • Множественные слэши: 10.0.0.0/24/8 теперь отклоняется

2. src/queries.js — транзакции + гонки

  • createEntry, updateEntry, deleteEntry — внутри транзакции с SELECT ... FOR UPDATE
  • getOrCreateCompany — атомарный INSERT ... ON CONFLICT
  • getLimit!= null вместо || (custom_limit=0 не игнорируется)
  • logAudit — принимает клиента транзакции (пишется атомарно)
  • getExportCIDRs — фильтр по companyId
  • deleteEntrycompany_id в WHERE

3. src/auth.jsновый. Мок JWT-аутентификация

  • Генерирует RSA-ключи при старте
  • JWKS endpoint: /.well-known/jwks.json
  • verifyJWT(token) — RS256, issuer: mock-auth-api
  • issueJWT(claims) — выпускает токен с claims как в HAR (ClientID, company_id, company_name, email)
  • Middleware: извлекает JWT из cookie (jwt) или Authorization: Bearer
  • DEV_MODE: при DEV_MODE=true && NODE_ENV!=production — обход auth
  • Для прода: выставить JWKS_URL=https://auth-api.../jwks → switches to external verification

4. views/login.ejsновый. Мок-страница входа

  • Выбор из 3 пользователей (admin WZ01112, тест WZ01325, компания 2 WZ02001)
  • В проде заменяется на редирект в Keycloak

5. server.js

  • cookie-parser для чтения JWT из cookie
  • /healthz — выше auth (k8s probe)
  • /login GET/POST — мок-логин
  • /logout — чистит cookie
  • /export — только для своей компании (с авторизацией)
  • req.query.error читается
  • urlencoded({ limit: '32kb' })

6. sql/schema.sql

  • UNIQUE INDEX на активный (company_id, value_cidr) WHERE deleted_at IS NULL
  • CHECK на value_cidr формат
  • CHECK на audit_log.action IN ('CREATE','UPDATE','DELETE')
  • CHECK на custom_limit IS NULL OR >= 0
  • FK: ON DELETE RESTRICT
  • Составной индекс (company_id, created_at DESC) на audit_log
  • Индекс (company_id, created_at DESC) на whitelist_entries

7. views/index.ejs

  • pattern + maxlength="18" + title на инпуте value

Ревью (/home/naeel/IPWhiteList/research/)

Файл Что
REVIEW-SUMMARY.md Сводка всех находок (11 критических, 21 средний)
opus-review-validators.md 1 критичный + 2 средних
opus-review-queries.md 3 гонки + audit + getLimit
opus-review-server.md JWT без подписи, 401, CSRF, /export
opus-review-schema.md UNIQUE, CIDR, FK, индексы
opus-review-ejs.md CSRF, clickjacking, client-валидация
auth-flow.md Анализ HAR: claims, цепочка auth-api

Не сделано (production-hardening, не баги)

  • helmet (X-Frame-Options, CSP, HSTS)
  • rate-limit на POST /add, /delete, /export
  • CSRF-токены в формах
  • JWT-верификация через внешний JWKS (нужен URL от девопсов)
  • Admin-признак в токене (нужен пример токена админа)
  • Multi-company (нужен формат claims от платформы)

Для прода

Выставить в .env:

NODE_ENV=production
JWKS_URL=<auth-api JWKS URL>

Всё остальное работает без изменений.