5.1 KiB
5.1 KiB
Сессия 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
<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:
// checkImpersonation — строка 78 (было)
const oldIsImp = !!(u.originalUserEmail && u.impersonatedCompanyId);
// applyContext — строка 133 (было)
const isImpersonated = !!(u.originalUserEmail && u.impersonatedCompanyId);
Поле impersonatedCompanyId отсутствует в ответе IAM. IAM /auth/user возвращает:
{
"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):
// checkImpersonation (исправлено)
const oldIsImp = !!u.isImpersonated;
// applyContext (исправлено)
const isImpersonated = !!(u.isImpersonated || u.originalUserEmail);
3. Время в аудите — UTC → MSK
Файл: views/v2/admin-audit.ejs, строка 100.
// Было (возвращает серверное время = 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 показывается как админ, потому что:
- IAM честно говорит
isAdmin: falseдляtazet@narod.ru - Но
applyContextпроверяетemail === ADMIN_EMAIL→true ADMIN_EMAIL=tazet@narod.ruв ENV
Это ожидаемое поведение — ADMIN_EMAIL даёт админские права независимо от IAM.