docs: session history 2026-06-11 with remaining tasks
This commit is contained in:
@@ -0,0 +1,128 @@
|
|||||||
|
# Сессия 2026-06-11 — Имперсонация, toggle, аудит
|
||||||
|
|
||||||
|
## Хронология
|
||||||
|
|
||||||
|
### 1. Починка toggle «Администратор»
|
||||||
|
**Проблема:** чекбокс не показывался.
|
||||||
|
**Причина:** `canAdminMode` вычислялся в `resolveUser`, но не передавался в `res.render`.
|
||||||
|
**Исправление:** добавлен `canAdminMode: req.user.canAdminMode` в `entries.js`.
|
||||||
|
|
||||||
|
### 2. Дубликат catch → крэш
|
||||||
|
При правке `ui/index.js` остался дубликат `} catch {`. Приложение падало при старте.
|
||||||
|
**Исправление:** удалён лишний catch.
|
||||||
|
|
||||||
|
### 3. JS onclick → form POST
|
||||||
|
Toggle не реагировал — сложный inline JS с `getComputedStyle` и `fetch`.
|
||||||
|
**Исправление:** заменён на `<form method="POST" action="/toggle-admin">`. Ноль JS.
|
||||||
|
|
||||||
|
### 4. Чужой email в header
|
||||||
|
Админ видел `nstasyuk@nubes.ru` вместо своего — шаблон показывал `selectedCompany.owner_email`.
|
||||||
|
**Исправление:** всегда показывать `user.email`.
|
||||||
|
|
||||||
|
### 5. Хардкод isNail
|
||||||
|
IAM не давал `isAdmin: true` для `ntazetdinov@nubes.ru`.
|
||||||
|
**Исправление:** временный хардкод `isNail` в `ui/index.js`.
|
||||||
|
|
||||||
|
### 6. canWrite из IAM
|
||||||
|
IAM возвращает `can_write: false` для всех — это IAM-шная RBAC, не наш флаг.
|
||||||
|
**Исправление:** `canWrite` убран полностью.
|
||||||
|
|
||||||
|
### 7. Имперсонация: флаги из IAM
|
||||||
|
Добавлены поля из IAM: `isImpersonated`, `originalUserEmail`, `originalUserFullName`, `impersonationType`.
|
||||||
|
**Файлы:** `src/auth.js:fetchIamUser`, `src/routes/oidc.js`, `ui/index.js:resolveUser`.
|
||||||
|
|
||||||
|
### 8. Баннер имперсонации
|
||||||
|
В `views/index.ejs` добавлен жёлтый баннер при `isImpersonated`.
|
||||||
|
|
||||||
|
### 9. Двойной аудит
|
||||||
|
Колонка `impersonated_by` в `audit_log`.
|
||||||
|
**Файлы:** `src/db.js` (миграция), `src/queries.js:logAudit`, `src/api/routes/entries.js`.
|
||||||
|
|
||||||
|
### 10. X-Imp-* заголовки — мост UI→API
|
||||||
|
UI-слой знал про имперсонацию, API-слой — нет.
|
||||||
|
**Исправление:** `api-client.js:impHeaders()`, `bearerMiddleware` читает `X-Imp-Email`, `X-Imp-OriginalEmail`, `X-Imp-ClientId`.
|
||||||
|
|
||||||
|
### 11. Безопасность: OIDC state check
|
||||||
|
`|| true` в `/callback` отключал проверку state во всех окружениях.
|
||||||
|
**Исправление:** убрано `|| true`.
|
||||||
|
|
||||||
|
### 12. Безопасность: open redirect
|
||||||
|
`POST /login-token` редиректил без `safeReturn`.
|
||||||
|
**Исправление:** добавлен `safeReturn(returnTo)`.
|
||||||
|
|
||||||
|
### 13. Безопасность: client_id без проверки
|
||||||
|
При пустом `allowedIds` можно было подставить любой `?client_id=`.
|
||||||
|
**Исправление:** `requestedId` принимается только если `allowedIds.length > 0`.
|
||||||
|
|
||||||
|
### 14. Тестовая имперсонация
|
||||||
|
Три env-переменные: `IMPERSONATION_ORIGINAL`, `IMPERSONATION_TARGET`, `IMPERSONATION_COMPANY`.
|
||||||
|
**Файл:** `ui/index.js` (блок `TEST IMPERSONATION`).
|
||||||
|
|
||||||
|
### 15. Часовой пояс GMT+4
|
||||||
|
`Europe/Moscow` → `Etc/GMT-4` в `views/index.ejs` и `views/audit.ejs`.
|
||||||
|
|
||||||
|
### 16. Аудит: колонка «Имперсонировал»
|
||||||
|
В `views/audit.ejs` добавлена колонка `impersonated_by`. Фильтр по компании — кнопка вместо JS.
|
||||||
|
|
||||||
|
### 17. Удалённые записи: визуал
|
||||||
|
Зачёркивание + полупрозрачность. Кнопки скрыты для удалённых.
|
||||||
|
**Файл:** `views/index.ejs`.
|
||||||
|
|
||||||
|
### 18. Чекбокс «Показать удалённые»
|
||||||
|
Возвращён в админ-режим.
|
||||||
|
**Файл:** `views/index.ejs`.
|
||||||
|
|
||||||
|
### 19. ТЗ-факт
|
||||||
|
Составлен документ `TZs/ТЗ-факт.md` — техзадание по фактически реализованному функционалу.
|
||||||
|
|
||||||
|
### 20. Сверка с требованиями Сергея
|
||||||
|
Прочитан `Files/wsm.txt`. Подтверждено соответствие. Не сделано: ссылка на запрещённые префиксы, текст-мануал от Стасюка.
|
||||||
|
|
||||||
|
## Основные файлы, изменённые в сессии
|
||||||
|
|
||||||
|
| Файл | Что |
|
||||||
|
|---|---|
|
||||||
|
| `ui/index.js` | canAdminMode, isNail, TEST IMPERSONATION, canWrite |
|
||||||
|
| `ui/routes/entries.js` | canAdminMode в render, impHeaders, упрощение ownCo |
|
||||||
|
| `ui/routes/auth.js` | toggle-admin redirect, open redirect fix |
|
||||||
|
| `ui/api-client.js` | impHeaders(), X-Imp-* заголовки |
|
||||||
|
| `src/auth.js` | fetchIamUser (все поля), bearerMiddleware (X-Imp-*), safeReturn |
|
||||||
|
| `src/routes/oidc.js` | isImpersonated в сессию, fix || true |
|
||||||
|
| `src/api/routes/entries.js` | impersonatedBy в queries, client_id fix, export JSON |
|
||||||
|
| `src/db.js` | ALTER TABLE impersonated_by |
|
||||||
|
| `src/queries.js` | logAudit с impersonatedBy |
|
||||||
|
| `views/index.ejs` | toggle (form POST), баннеры, удалённые записи, includeDeleted |
|
||||||
|
| `views/audit.ejs` | колонка impersonated_by, кнопка фильтра, GMT+4 |
|
||||||
|
| `server.js` | debug-session с lastAudit |
|
||||||
|
|
||||||
|
## Ветки
|
||||||
|
- `save-2026-06-11` — снапшот перед критичными фиксами
|
||||||
|
- `save-2026-06-12` — финальное состояние
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что осталось (для следующего чата)
|
||||||
|
|
||||||
|
### Баги
|
||||||
|
1. **Toggle виден при имперсонации** — по требованию Сергея: «Когда я имперсонирую — вижу то же что пользователь». При имперсонации `canAdminMode` должен быть false (сейчас true, потому что вычисляется из оригинального JWT, а не из `activeClientId`). `ui/index.js` строка 65-67.
|
||||||
|
2. **Email в header берётся из `payload.email`**, а не из `req.session?.user?.email`. Иногда показывает чужой email. `ui/index.js` строка 75.
|
||||||
|
|
||||||
|
### Не сделано по ТЗ/требованиям Сергея
|
||||||
|
3. Ссылка на список зарезервированных префиксов (14 диапазонов)
|
||||||
|
4. Краткий мануал на главной для пользователей (ждём от Стасюка)
|
||||||
|
|
||||||
|
### Временные решения (убрать при настройке IAM)
|
||||||
|
5. `isNail` — хардкод `ntazetdinov@nubes.ru` как админ. Заменить на `isAdmin` из IAM. `ui/index.js` строка 63.
|
||||||
|
6. `TEST IMPERSONATION` — env-переменные. Убрать для прода. `ui/index.js` строки 70-78.
|
||||||
|
|
||||||
|
### Архитектурный долг
|
||||||
|
7. Дублирование `buildSessionUser` в `oidc.js` и `auth.js`
|
||||||
|
8. Флаги `isAdmin`/`adminMode`/`canAdminMode`/`isNail` — упростить до двух
|
||||||
|
9. Циклическая зависимость `ui → src/auth` через `require('../../src/auth')`
|
||||||
|
|
||||||
|
## Как работать дальше
|
||||||
|
|
||||||
|
1. Прочитать ТЗ: `TZs/ТЗ-факт.md` (фактическое), `docs/ТЗ.md` (оригинал)
|
||||||
|
2. Прочитать требования Сергея: `Files/wsm.txt` (особенно строки 378-470)
|
||||||
|
3. Начать с бага №1 (toggle + имперсонация) — это противоречит требованию заказчика
|
||||||
|
|
||||||
Reference in New Issue
Block a user