From e2aaf3f425f7f8329eb8b3a76e49d9092b531fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 15 Jun 2026 16:16:36 +0400 Subject: [PATCH] =?UTF-8?q?v0.5.123:=20switchTo=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=20crud.list,=20activeClientId=20=D0=BD=D0=B5=20=D0=B7?= =?UTF-8?q?=D0=B0=D1=82=D0=B8=D1=80=D0=B0=D0=B5=D1=82=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/switch-company-bug.md | 76 +++++++++++++++++++++++++++++++++++ package.json | 2 +- v2/src/config/index.js | 2 +- v2/src/impersonation/index.js | 2 +- v2/src/user/index.js | 22 ++++------ 5 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 docs/switch-company-bug.md diff --git a/docs/switch-company-bug.md b/docs/switch-company-bug.md new file mode 100644 index 0000000..e756da2 --- /dev/null +++ b/docs/switch-company-bug.md @@ -0,0 +1,76 @@ +# Баг: переключение компании — таблица IP не обновляется + +## Симптом +GET /v2/app?switchTo=WZ30001 → таблица показывает записи старой компании. + +## Найденная причина №1 (основная) +Порядок кода в `v2/src/user/index.js`: + +```js +// 1. clId = req.clientId ← resolveContext выставил СТАРЫЙ activeClientId +const clId = req.clientId; + +// 2. crud.list() по СТАРОМУ clId — ещё до switchTo +const { entries, used, limit } = await crud.list(clId, includeDeleted); + +// 3. Потом switchTo обновляет сессию и делает redirect +if (req.query.switchTo) { + req.session.user.activeClientId = targetId; + return req.session.save(() => res.redirect('/v2/app')); +} +``` + +Итог: первый запрос с ?switchTo загружает записи СТАРОЙ компании. +Второй запрос (редирект /v2/app) должен уже использовать новый activeClientId — если ничто его не затирает. + +## Найденная причина №2 (если ENV заданы) +`v2/src/impersonation/index.js` — при тестовом режиме (IMPERSONATION_TARGET задан): + +```js +u.activeClientId = MAIN_COMPANY; // ← затирает то что записал switchTo +``` + +Middleware запускается при КАЖДОМ запросе (включая редирект после switchTo) +и сбрасывает activeClientId обратно в IMPERSONATION_COMPANY. + +## Что проверить +```bash +echo $IMPERSONATION_COMPANY +echo $IMPERSONATION_TARGET +echo $IMPERSONATION_ORIGINAL +``` + +Если заданы → причина №2 (middleware затирает сессию). +Если не заданы → причина №1 (но тогда второй запрос после редиректа должен работать). + +## Фикс причины №1 +В `v2/src/user/index.js` — переставить проверку switchTo ПЕРЕД crud.list(): + +```js +// Сначала switchTo +if (req.query.switchTo) { + const targetId = req.query.switchTo; + const allowed = isAdmin || (req.profiles || []).find(p => p.client_id === targetId); + if (allowed) { + req.session.user.activeClientId = targetId; + return req.session.save(err => { + if (err) console.error('[switchTo] save error:', err.message); + res.redirect('/v2/app'); + }); + } +} + +// Потом загружать записи +const { entries, used, limit } = await crud.list(clId, includeDeleted); +``` + +## Фикс причины №2 +В `v2/src/impersonation/index.js` — не перезаписывать activeClientId если он уже есть: + +```js +// Вместо: +u.activeClientId = MAIN_COMPANY; + +// Сделать: +u.activeClientId = u.activeClientId || MAIN_COMPANY; +``` diff --git a/package.json b/package.json index 504b8fb..e8eae87 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.5.122", + "version": "0.5.123", "description": "IP WhiteList microservice for cloud provider", "main": "server.js", "scripts": { diff --git a/v2/src/config/index.js b/v2/src/config/index.js index 24d7a72..d553ccc 100644 --- a/v2/src/config/index.js +++ b/v2/src/config/index.js @@ -9,7 +9,7 @@ // ═══════════════════════════════════════════════════════════════════════════════ module.exports = { - version: '0.5.122', + version: '0.5.123', // ── IAM ────────────────────────────────────────────────────────────────── iamUrl: process.env.V2_IAM_URL || 'https://auth-api.ngcloud.ru/api/v1/auth/user', diff --git a/v2/src/impersonation/index.js b/v2/src/impersonation/index.js index fc830b4..02cb3d0 100644 --- a/v2/src/impersonation/index.js +++ b/v2/src/impersonation/index.js @@ -40,7 +40,7 @@ function enhanceImpersonation(req, res, next) { // Подменяем ВСЕ данные на таргета (как делает IAM) u.email = TARGET_EMAIL; u.clientId = MAIN_COMPANY; - u.activeClientId = MAIN_COMPANY; + u.activeClientId = u.activeClientId || MAIN_COMPANY; u.allClientIds = ALL_TARGET_CIDS; u.companyName = MAIN_COMPANY; u.isAdmin = wasAdmin; diff --git a/v2/src/user/index.js b/v2/src/user/index.js index 6e17cf8..420c935 100644 --- a/v2/src/user/index.js +++ b/v2/src/user/index.js @@ -49,31 +49,23 @@ function createUserRouter() { : [{ client_id: clId, name: req.companyName || clId, is_active: true }]; } - // ── Записи ────────────────────────────────────────────────────── - const includeDeleted = req.query.deleted === '1'; - const { entries, used, limit } = await crud.list(clId, includeDeleted); - - // ── Переключение компании ────────────────────────────────────── + // ── Переключение компании (до crud.list — не грузить зря) ──── if (req.query.switchTo) { const targetId = req.query.switchTo; - if (isAdmin) { + const allowed = isAdmin || (req.profiles || []).find(p => p.client_id === targetId); + if (allowed) { req.session.user.activeClientId = targetId; return req.session.save(err => { if (err) console.error('[switchTo] save error:', err.message); res.redirect('/v2/app'); }); - } else { - const allowed = (req.profiles || []).find(p => p.client_id === targetId); - if (allowed) { - req.session.user.activeClientId = targetId; - return req.session.save(err => { - if (err) console.error('[switchTo] save error:', err.message); - res.redirect('/v2/app'); - }); - } } } + // ── Записи ────────────────────────────────────────────────────── + const includeDeleted = req.query.deleted === '1'; + const { entries, used, limit } = await crud.list(clId, includeDeleted); + // ── Данные пользователя для шаблона ──────────────────────────── const sessionUser = req.session && req.session.user ? req.session.user : {}; const templateUser = {