Files
ipwhitelist-app/docs/ТЗ-плюс.md
naeel a8a07fe019 feat: IAM API интеграция + обновление ТЗ + тесты
- 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
2026-06-04 13:53:44 +03:00

206 lines
7.4 KiB
Markdown

# ТЗ-плюс — уточнения и дополнения от заказчика
> Основа: `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):
```json
{
"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` |
| Email | `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. Тестовые данные
| Email | 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 работает |
---
## Легенда статусов
| 🔴 | Требует уточнения |
| 🟡 | Уточнено, не реализовано |
| 🟢 | Реализовано / подтверждено |
| ⚫ | Отменено / не актуально |