- src/auth.js: fetchIamUser(), switchProfile(), userFromPayload(iamData) - src/config.js: IAM_API_URL из env - src/routes/oidc.js: обогащение сессии через IAM (с fallback на JWT) - ui/routes/auth.js: обогащение при токен-логине - ui/routes/entries.js: switchTo через POST /switch-profile - src/api/routes/entries.js: resolveCompany через profiles[] - views/index.ejs: переключатель компаний с названиями из profiles - .env.example: IAM_API_URL - docs: обновлены ТЗ-реализация.md, ТЗ-плюс.md, добавлен iam-integration.md - tests: api-crud.sh (14 тестов CRUD + валидации) - .gitignore: исключены .env.test, DEPLOY-TESTING.md
7.4 KiB
ТЗ-плюс — уточнения и дополнения от заказчика
Основа:
docs/ТЗ.md
Дата последнего обновления: 2026-06-04
Файл для фиксации уточнений, дополнений и решений.
1. Аутентификация — интеграция с IAM API
1.1. IAM API — единый сервис авторизации (УТОЧНЕНО 04.06.2026)
IAM (Identity & Access Management) — сервис авторизации экосистемы Nubes. Все смежные сервисы ходят в него для проверки компании пользователя.
Три стенда:
| Стенд | URL |
|---|---|
| Dev | https://auth-api-dev.ngcloud.ru |
| Test | https://auth-api-test.ngcloud.ru |
| Prod | https://auth-api.ngcloud.ru |
Swagger: https://auth-api-dev.ngcloud.ru/api/v1/documentation/
Исходный источник: CRM Elma (контакт, компания, отношение N:M).
Статус: 🟢 подтверждено
1.2. Поток аутентификации (УТОЧНЕНО 04.06.2026)
Пользователь → Keycloak (SSO) → IAM (обмен code) → access_token + refresh_token
│
┌───────────────────────────────┘
▼
GET /api/v1/auth/user (Bearer access_token)
│
▼
{ profiles[], userInfo }
access_token от IAM (token_type: "access", TTL 12 часов) сразу годится для
вызова GET /api/v1/auth/user. Никакого дополнительного обмена не требуется.
Статус: 🟢 подтверждено (Node.js HTTP 200, получен реальный ответ)
1.3. client_id приложения в Keycloak
- Источник: HAR-файл
- Факт:
client_idв URL auth-запроса - Статус: 🔴 требует подтверждения
1.4. JWKS URL и Redirect URI
- Статус: 🔴 требует подтверждения DevOps
2. Компании пользователя — IAM /auth/user
2.1. GET /api/v1/auth/user (УТОЧНЕНО 04.06.2026)
Реальный ответ (пользователь tazetdinovn@gmail.com, prod):
{
"profiles": [
{
"id": 4357,
"client_id": "WZ03709",
"company_id": "019cc24a-727e-740f-b407-bec79dab4162",
"company_name": "naeel_test",
"company_numeric_id": 2645,
"is_active_profile": true
}
],
"userInfo": {
"clientID": "WZ03709",
"company": "naeel_test",
"companyId": "019cc24a-727e-740f-b407-bec79dab4162",
"companyNumericId": 2645,
"email": "tazetdinovn@gmail.com",
"isAdmin": false,
"fio": {"fullName": "Тазетдинов Наиль Фаритович", "name": "Наиль", "secondName": "Фаритович", "surname": "Тазетдинов"},
"contactId": "019cc268-6c6a-781e-8613-4bed4ec7cd20",
"elmaUserId": 39715
}
}
Маппинг полей для использования в коде:
| Назначение | Откуда |
|---|---|
| Список WZ-кодов компаний | profiles[].client_id |
| Активная компания | profiles[].is_active_profile === true |
| ID для switch-profile | profiles[].id |
| WZ активной компании | userInfo.clientID |
| Название компании | userInfo.company |
| UUID компании | userInfo.companyId |
| Флаг админа | userInfo.isAdmin |
userInfo.email |
Статус: 🟢 подтверждено
2.2. POST /api/v1/user/switch-profile (УТОЧНЕНО 04.06.2026)
Тело: {"profile_id": 3120} или {"company_id": "uuid"}.
Статус: 🟡 уточнено по Swagger, не тестировалось на живом multi-company юзере
2.3. ⚫ ClientID через запятую в JWT — УСТАРЕЛО
- Было (01.06):
ClientID: "WZ11125, WZ03816"в claims JWT - Стало (04.06): JWT содержит только ОДНУ компанию (активную).
Правильный источник списка —
profiles[]из IAM API. - Статус: ⚫ отменено
2.4. ⚫ Admin = WZ01112 — УСТАРЕЛО
- Было:
clientId === 'WZ01112'→ админ - Стало:
userInfo.isAdminиз IAM API - Статус: ⚫ отменено
3. Сетевая доступность
3.1. ddos-guard (УТОЧНЕНО 04.06.2026)
Все *.ngcloud.ru за ddos-guard. IP 81.200.23.210 не блокируется —
проблема в HTTP-клиенте:
| Клиент | auth-api | deck-api-test |
|---|---|---|
curl (без --http2) |
❌ 403 | ❌ 403 |
curl --http2 |
✅ 200 | ❌ 403 |
Node.js https |
✅ 200 | ✅ 200 |
| Браузер | ✅ 200 | ✅ 200 |
Правило для curl: --http2 + Accept: application/json.
Node.js (приложение): работает без проблем.
Статус: 🟢 подтверждено
4. Инфраструктура и деплой
- Платформа: 🔴 уточнить
- CI/CD: 🔴 уточнить
- Сетевое ограничение /export: 🔴 уточнить
5. Функциональные уточнения
5.1. Мульти-компания в UI
- Список компаний из
profiles[], активная поis_active_profile - Переключение: UI →
POST /switch-profileна IAM → обновить сессию - Статус: 🟡 требует реализации
5.2. Soft-delete фильтр
includeDeletedвсегдаfalse- Статус: 🟡 не реализовано
5.3. Индивидуальные лимиты
- Статус: 🔴 проверить
5.4. Уведомление о нормализации
- Статус: 🔴 проверить
6. Тестовые данные
| ClientID | Компания | Роль | |
|---|---|---|---|
tazetdinovn@gmail.com |
WZ03709 | naeel_test | Пользователь |
client@example.com |
WZ01325 | Тест | Клиент |
admin@nubes.ru |
WZ01112 | Нубес | Админ |
HAR-сессия
- Файл:
Files/nubes_login.har, пользовательtazet@narod.ru, deck-test
7. Принятые решения
| Дата | Решение |
|---|---|
| 01.06.2026 | Экспорт: txt, одна строка = один CIDR |
| 01.06.2026 | Демо одобрено |
| 02.06.2026 | Любой юзер компании редактирует whitelist всей компании |
| 04.06.2026 | IAM API — источник компаний. GET /auth/user → profiles[]. isAdmin из userInfo.isAdmin. Переключение через POST /switch-profile. |
| 04.06.2026 | ddos-guard: curl требует --http2, Node.js работает |
Легенда статусов
| 🔴 | Требует уточнения | | 🟡 | Уточнено, не реализовано | | 🟢 | Реализовано / подтверждено | | ⚫ | Отменено / не актуально |