# IP WhiteList — План (pending задачи, 2026-05-30 14:43) > **Ветка:** `sonnet` · **Обновлено:** 2026-05-30 14:43 > Всё что было в старых планах — реализовано. Здесь только то, чего ещё нет. --- ## Блокер 1 — Keycloak OIDC (нужны данные от DevOps) Код OIDC Authorization Code Flow написан и готов (`src/auth.js`). Не активируется пока не получены: | Что нужно | Env-переменная | Статус | |---|---|---| | client_id в realm cloud | `KC_CLIENT_ID` | ❌ ждём DevOps | | client_secret | `KC_CLIENT_SECRET` | ❌ ждём DevOps | | redirect_uri зарегистрирован в KK | (в самом KK) | ❌ ждём DevOps | | SESSION_SECRET для продакшена | `SESSION_SECRET` | ❌ нужно сгенерировать | Без этого сервис работает в mock-режиме (`/dev-login` как тестовый backdoor). --- ## Блокер 2 — Admin-роль из Keycloak Сейчас admin = `clientId === WZ01112`. Как реально приходит `isAdmin` из KK — не ясно (см. [questions.md](questions.md)). После получения ответа — 1–2 строки в `userFromPayload()` в `src/auth.js`. --- ## Задача 1 — Деплой ветки sonnet - [ ] Передеплоить на `white.nodejsk8s.dev.nubes.ru` (сейчас там master) - [ ] Добавить env-секреты в k8s: `SESSION_SECRET`, `CSRF_SECRET` - [ ] Проверить smoke-тест: `/healthz`, `/login`, `/export` --- ## Задача 2 — Сессии при multi-pod Сейчас: MemoryStore (in-process, не масштабируется). При нескольких репликах k8s сессии будут теряться. - [ ] `npm install connect-redis ioredis` - [ ] Подключить Redis в `server.js` (3 строки конфига) - [ ] Добавить `REDIS_URL` в env **Блокер:** нужен Redis в k8s (или принять ограничение на 1 реплику пока). --- ## Задача 3 — IP-ограничение /export ТЗ: endpoint доступен без авторизации, ограничен по IP на старте. Текущее решение: открытый endpoint с rate-limit (20 req/мин). - [ ] Уточнить: ограничение в приложении или ingress? (см. [questions.md](questions.md)) - [ ] Если в приложении: whitelist IP через `EXPORT_ALLOWED_IPS` env var --- ## Задача 4 — Пагинация При `custom_limit` > 50 таблица станет неудобной. Сейчас все записи выводятся без пагинации. - [ ] `GET /?page=N` + `LIMIT/OFFSET` в `queries.listEntries()` - [ ] Кнопки Назад/Вперёд в `views/index.ejs` Низкий приоритет — текущий дефолтный лимит 15 записей на компанию. --- ## Задача 5 — Auto-dismiss alert Flash-алерты (ошибка/успех) сейчас исчезают только при перезагрузке. - [ ] 10 строк JS в `views/index.ejs`: `setTimeout(() => alert.remove(), 5000)` --- ## Не делать (закрыто) | Что | Почему | |---|---| | ~~CSRF-защита~~ | ✅ csrf-csrf (double-submit cookie) | | ~~Рефакторинг server.js~~ | ✅ 131 строка, роутеры вынесены | | ~~Автотесты~~ | ✅ 50 unit-тестов (`node tests/run-tests.js`) | | ~~aggregateCIDRs в /export~~ | ✅ в `src/validators.js` | | ~~Admin-панель~~ | ✅ `src/routes/admin.js`, `views/admin.ejs` | | ~~Редактирование записи~~ | ✅ `POST /edit/:id` | | ~~Аудит~~ | ✅ `GET /audit` | | ~~OIDC Authorization Code Flow~~ | ✅ `src/auth.js` + `src/routes/auth.js` | | ~~Session middleware~~ | ✅ `express-session` в `server.js` | | ~~Dev-login backdoor~~ | ✅ `/dev-login` с пресетами + кастомные поля |