130 lines
5.6 KiB
Markdown
130 lines
5.6 KiB
Markdown
# V2 — история 2026-06-12 (финал)
|
||
|
||
## V2 — это тестовый стенд для модулей
|
||
|
||
Код в `v2/` — НЕ production. Это полигон для отладки модулей.
|
||
Каждый модуль тестируется изолированно, затем будет интегрирован в основной код.
|
||
|
||
## Текущее состояние (0.5.73)
|
||
|
||
```
|
||
v2/
|
||
├── server.js # createV2Router() → /v2/login, /v2/iam, /v2/logout
|
||
├── src/
|
||
│ ├── auth/index.js # fetchIamUser(), login(), exchangeCode(), buildAuthUrl()
|
||
│ ├── config/index.js # iamUrl, appUrl, version (без KC — пока не нужен)
|
||
│ ├── crud/index.js # createCrudRouter() — НЕ монтирован (будет позже)
|
||
│ ├── db/
|
||
│ │ ├── index.js # pg pool
|
||
│ │ ├── queries.js # CRUD SQL
|
||
│ │ └── schema.js # ensureSchema(pool) — автосоздание v2_* таблиц
|
||
│ └── validators/index.js # CIDR validate, overlaps, BLOCKED_RANGES
|
||
└── history/
|
||
└── 2026-06-12.md
|
||
```
|
||
|
||
## Как работает сейчас
|
||
|
||
1. `/v2/login` → редирект на `/login?returnTo=/v2/iam`
|
||
2. Основной OIDC: production-KC → `/callback` → сессия → редирект на `/v2/iam`
|
||
3. `/v2/iam` → показывает IAM-данные из `req.session.user`
|
||
|
||
V2 НЕ делает свой OIDC. Использует готовую сессию основного приложения.
|
||
Никаких своих KC-настроек. Никакого `/v2/callback`.
|
||
|
||
## Модуль auth/index.js — готов, но не используется
|
||
|
||
Функции готовы к production:
|
||
- `buildAuthUrl(config)` — URL редиректа на KC
|
||
- `exchangeCode(code, config)` — обмен code → токен
|
||
- `fetchIamUser(token, iamUrl)` — IAM → профиль
|
||
- `generateState()` — CSRF
|
||
- `login(code, oidcConfig, iamUrl)` — оркестратор
|
||
|
||
Не тестировались: нужен `/v2/callback` в redirect URIs production-KC.
|
||
|
||
## Модуль crud/ — готов, не монтирован
|
||
|
||
Функции:
|
||
- `createCrudRouter()` — роутер с выбором компании (всегда список, даже если одна)
|
||
- CRUD через `db/queries.js`
|
||
|
||
Таблицы: v2_companies, v2_entries, v2_audit (автосоздание через schema.js).
|
||
|
||
## Модуль db/ — готов
|
||
|
||
- `db/index.js` — pg pool
|
||
- `db/queries.js` — getOrCreateCompany, listEntries, createEntry, updateEntry, deleteEntry, getAudit, ...
|
||
- `db/schema.js` — ensureSchema(pool) — CREATE TABLE IF NOT EXISTS
|
||
|
||
## Модуль validators/ — готов
|
||
|
||
CIDR validate, overlaps, cidrToRange, aggregateCIDRs, BLOCKED_RANGES.
|
||
|
||
## Что дальше
|
||
|
||
1. fio в fetchIamUser — возвращать строку (сейчас объект)
|
||
2. Добавить `/v2/callback` в redirect URIs production-KC
|
||
3. Протестировать auth/login() с production-KC
|
||
4. Подключить crud модуль
|
||
5. Админка, экспорт
|
||
|
||
## Ключевые решения
|
||
|
||
- V2 НЕ трогает основной код (server.js — только app.use('/v2', ...))
|
||
- Каждый модуль — отдельная папка в src/
|
||
- env-переменные — через process.env, без .env/dotenv
|
||
- Умолчания — хардкод, переопределяются через V2_* env
|
||
|
||
---
|
||
|
||
## Модуль router/ (0.5.75)
|
||
|
||
`resolveContext` middleware — определяет контекст из `req.session.v2_user`:
|
||
|
||
```
|
||
нет сессии / нет v2_user → 302 /v2/login
|
||
обычный юзер → req.v2_email, req.v2_clientId (activeClientId)
|
||
юзер с несколькими компаниями → activeClientId из сессии
|
||
админ + adminMode → req.v2_isAdmin = true
|
||
админ без adminMode → req.v2_isAdmin = false (видит как юзер)
|
||
имперсонация → email подменён на originalUserEmail
|
||
clientId подменён на impersonatedCompanyId
|
||
req.v2_impersonatedBy = реальный админ
|
||
```
|
||
|
||
### Тесты (v2/src/router/test.js)
|
||
|
||
9 тестов, все пройдены ✅:
|
||
|
||
1. нет сессии → /v2/login
|
||
2. нет v2_user → /v2/login
|
||
3. обычный юзер 1 компания
|
||
4. юзер 2 компании → activeClientId
|
||
5. админ adminMode=true
|
||
6. админ adminMode=false
|
||
7. имперсонация с originalUserEmail
|
||
8. имперсонация без originalUserEmail
|
||
9. без activeClientId → fallback на clientId
|
||
|
||
### Ошибки при тестировании
|
||
|
||
- Причина: спешка. null вместо undefined, двойной префикс v2_v2_ в ключах.
|
||
- Урок: сначала думать, потом писать.
|
||
|
||
## Текущая структура (0.5.75)
|
||
|
||
```
|
||
v2/src/
|
||
├── auth/index.js # fetchIamUser(), login(), exchangeCode()
|
||
├── config/index.js # iamUrl, appUrl, version
|
||
├── router/
|
||
│ ├── index.js # resolveContext middleware
|
||
│ └── test.js # 9 тестов
|
||
├── user/index.js # createUserRouter (пустышка)
|
||
├── admin/index.js # createAdminRouter (пустышка)
|
||
├── crud/index.js # createCrudRouter (не монтирован)
|
||
├── db/ # pool, queries, schema
|
||
└── validators/index.js # CIDR validate
|
||
```
|