документация: сессия 2026-06-22 — export view=2, баг имперсонации, TZ аудит

This commit is contained in:
2026-06-22 23:59:15 +04:00
parent f898aabe7d
commit 4ee032ba8d
@@ -0,0 +1,135 @@
# Сессия 2026-06-22 — export view=2, фикс имперсонации, TZ аудит
## Версии
- **0.1.1** — сброс версии с 0.5.180
- **0.1.2** — `white-space: pre` на `<code>` (пробелы схлопывались)
- **0.1.3** — таблица без точек, октеты в своих `<td>`
- **0.1.4** — `text-align: right` в ячейках
- **0.1.5** — `padStart(2)` плотнее (один пробел, не два)
- **0.1.6** — фикс детекции имперсонации
- **0.1.7** — аудит: время Москвы вместо UTC
---
## 1. Export view=2 — HTML-таблица с выровненными IP
### Устройство
Файл: `v2/src/export/index.js`
Три режима:
| Параметр | Content-Type | Поведение |
|---|---|---|
| (нет) | `text/plain` | Скачивание `.txt` |
| `?view=1` | `text/plain` | Inline в браузере |
| `?view=2` | `text/html` | Таблица: 4 ячейки октетов + маска |
### Структура view=2
```html
<table>
<tr>
<td> 62</td><td> 76</td><td> 39</td><td> 5</td><td> / 32</td>
</tr>
</table>
```
- Каждый октет в своей `<td>`, без точек
- `padStart(2, ' ')` — минимум 2 символа на октет
- `text-align: right` — выравнивание по правой границе
- `white-space: pre` — пробелы не схлопываются
- Границы не видны (`border-collapse: collapse`, без `border` на td)
---
## 2. Фикс имперсонации — БАГ
### Симптом
На странице `/v2/app` не показывался баннер «Режим имперсонации», хотя IAM API возвращал `is_impersonated: true`.
### Причина
В двух местах `v2/src/router/index.js` проверка имперсонации использовала `u.impersonatedCompanyId`:
```js
// checkImpersonation — строка 78 (было)
const oldIsImp = !!(u.originalUserEmail && u.impersonatedCompanyId);
// applyContext — строка 133 (было)
const isImpersonated = !!(u.originalUserEmail && u.impersonatedCompanyId);
```
**Поле `impersonatedCompanyId` отсутствует в ответе IAM.** IAM `/auth/user` возвращает:
```json
{
"impersonation": {
"is_impersonated": true,
"impersonatedUserId": "...",
"originalUserEmail": "ntazetdinov@nubes.ru",
"originalUserFullName": "...",
"originalUserCompany": "...",
"sessionId": 613,
...
// ⚠️ impersonatedCompanyId — НЕТ
}
}
```
Из-за этого:
- `u.impersonatedCompanyId` всегда `''` (пустая строка = falsy)
- `!!(truthy && falsy)` → всегда `false`
- Баннер не показывался
- `checkImpersonation` на каждый запрос заново дёргал IAM (думал что статус изменился)
### Исправление
Заменить проверку на `u.isImpersonated` (которое корректно выставляется в `checkImpersonation`):
```js
// checkImpersonation (исправлено)
const oldIsImp = !!u.isImpersonated;
// applyContext (исправлено)
const isImpersonated = !!(u.isImpersonated || u.originalUserEmail);
```
---
## 3. Время в аудите — UTC → MSK
Файл: `views/v2/admin-audit.ejs`, строка 100.
```js
// Было (возвращает серверное время = UTC):
new Date(a.created_at).toLocaleString('ru')
// Стало (Москва, UTC+3):
new Date(a.created_at).toLocaleString('ru-RU', { timeZone: 'Europe/Moscow' })
```
---
## 4. Проверка IAM API
Три эндпоинта, проверены через Node.js с IAM-токеном (`iss: auth-api`):
| Эндпоинт | Статус | Результат |
|---|---|---|
| `auth-api /auth/user` | 200 | Полные данные + имперсонация |
| `lk-api-gateway /iam/auth/user` | 200 | **Идентично** auth-api |
| `auth-api /impersonation/status` | 200 | `is_impersonating`, `session_id`, etc. |
Данные между `auth-api` и `lk-api-gateway` совпадают поле-в-поле.
### Важно: токены
- **Keycloak-токен** (iss: `auth.k8s.ngcloud.ru`) → IAM возвращает 401 (не может проверить подпись)
- **IAM-токен** (iss: `auth-api`) → работает
- **Tech-токен** (8541 символ) → nginx 400 (превышен лимит заголовка 8KB)
- Для проверки API нужен IAM-токен из активной сессии
---
## 5. Админ при имперсонации
`tazet@narod.ru` показывается как админ, потому что:
1. IAM честно говорит `isAdmin: false` для `tazet@narod.ru`
2. Но `applyContext` проверяет `email === ADMIN_EMAIL``true`
3. `ADMIN_EMAIL=tazet@narod.ru` в ENV
Это ожидаемое поведение — `ADMIN_EMAIL` даёт админские права независимо от IAM.