From 9e3ba1c97c4da0abb3b7b0dc1f6915121ccc6c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Tue, 16 Jun 2026 05:53:31 +0400 Subject: [PATCH] =?UTF-8?q?v0.5.142:=20URL-=D0=B8=D0=BC=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D1=81=D0=BE=D0=BD=D0=B0=D1=86=D0=B8=D1=8F,=20=D1=83=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D1=8B=20=D1=81=D1=82=D0=B0=D1=80=D1=8B=D0=B5?= =?UTF-8?q?=20ENV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- v2/src/config/index.js | 2 +- v2/src/impersonation/index.js | 85 +++++++++++++++-------------------- 3 files changed, 38 insertions(+), 51 deletions(-) diff --git a/package.json b/package.json index aa0d39d..06a3576 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.5.141", + "version": "0.5.142", "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 d2c459d..9126f63 100644 --- a/v2/src/config/index.js +++ b/v2/src/config/index.js @@ -9,7 +9,7 @@ // ═══════════════════════════════════════════════════════════════════════════════ module.exports = { - version: '0.5.141', + version: '0.5.142', // ── 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 a82581d..c5474e9 100644 --- a/v2/src/impersonation/index.js +++ b/v2/src/impersonation/index.js @@ -1,73 +1,60 @@ // ═══════════════════════════════════════════════════════════════════════════════ -// V2 — Имперсонация (IAM + тестовый режим через ENV) +// V2 — Имперсонация (IAM + URL-режим) // -// ЭТО: middleware — имитирует IAM-имперсонацию для тестов. +// ЭТО: middleware — подмена сессии при имперсонации. // НЕ: жёсткая логика в resolveContext или user/index.js. // -// ТЕСТОВЫЙ РЕЖИМ (если задан IMPERSONATION_TARGET): -// При входе IMPERSONATION_ORIGINAL все данные сессии заменяются на TARGET. -// Полная имитация IAM-имперсонации: email, profiles, clientId — всё от таргета. +// IAM-имперсонация: если сессия уже содержит isImpersonated=true → не трогаем. +// +// URL-имперсонация: для разрешённых пользователей (IMPERSONATION_ALLOWED_USERS). +// /v2/app?impersonate=email&company=W*** +// Полная подмена сессии: email, clientId, profiles — всё от таргета. // // ENV: -// IMPERSONATION_ORIGINAL — email админа (кто имперсонирует) -// IMPERSONATION_TARGET — email юзера (кого имперсонируют) ← тест -// IMPERSONATION_COMPANY — W-номер основной компании таргета -// IMPERSONATION_EXTRA_COMPANIES — доп. W-номера через запятую +// IMPERSONATION_ALLOWED_USERS — emails через запятую (кому можно) // ═══════════════════════════════════════════════════════════════════════════════ -const ORIGINAL_EMAIL = process.env.IMPERSONATION_ORIGINAL || ''; -const TARGET_EMAIL = process.env.IMPERSONATION_TARGET || ''; -const MAIN_COMPANY = process.env.IMPERSONATION_COMPANY || ''; -const EXTRA_COMPANIES = (process.env.IMPERSONATION_EXTRA_COMPANIES || '') - .split(',').map(s => s.trim()).filter(Boolean); -const ALL_TARGET_CIDS = [...new Set([MAIN_COMPANY, ...EXTRA_COMPANIES].filter(Boolean))]; +const ALLOWED_USERS = new Set( + (process.env.IMPERSONATION_ALLOWED_USERS || '') + .split(',').map(s => s.trim()).filter(Boolean) +); function enhanceImpersonation(req, res, next) { const u = req.session && req.session.user; if (!u) return next(); - // ── IAM-имперсонация (уже есть в сессии) — просто добавляем компании ── - if (u.isImpersonated && u.originalUserEmail === ORIGINAL_EMAIL) { - addExtraCompanies(u); - return next(); - } + // ── IAM-имперсонация — уже в сессии, не трогаем ──────────────────── + if (u.isImpersonated) return next(); + + // ── URL-имперсонация ─────────────────────────────────────────────── + const targetEmail = req.query.impersonate; + const targetCompany = req.query.company; + + if (targetEmail && targetCompany && ALLOWED_USERS.has(u.email)) { + // Сохраняем оригинал + const origEmail = u.email; + const origFio = u.fio; - // ── Тестовый режим: нужны все три — ORIGINAL, TARGET, COMPANY ──────── - if (ORIGINAL_EMAIL && TARGET_EMAIL && MAIN_COMPANY && u.email === ORIGINAL_EMAIL) { // Подменяем ВСЕ данные на таргета (как делает IAM) - u.email = TARGET_EMAIL; - u.clientId = MAIN_COMPANY; - u.activeClientId = u.activeClientId || MAIN_COMPANY; - u.allClientIds = ALL_TARGET_CIDS; - u.companyName = MAIN_COMPANY; + u.email = targetEmail; + u.clientId = targetCompany; + u.activeClientId = targetCompany; + u.allClientIds = [targetCompany]; + u.companyName = targetCompany; u.isImpersonated = true; - u.impersonatedCompanyId = MAIN_COMPANY; - u.originalUserEmail = ORIGINAL_EMAIL; - u.originalUserFullName = u.fio ? (u.fio.fullName || '') : ''; + u.originalUserEmail = origEmail; + u.originalUserFullName = origFio ? (origFio.fullName || '') : ''; + u.impersonatedCompanyId = targetCompany; u.fio = null; - u.profiles = ALL_TARGET_CIDS.map(cid => ({ - client_id: cid, - company_name: cid, - is_active_profile: cid === MAIN_COMPANY, - })); - - return next(); + u.profiles = [{ + client_id: targetCompany, + company_name: targetCompany, + is_active_profile: true, + }]; } - // ── Не имперсонация — ничего не делаем ────────────────────────────── next(); } -function addExtraCompanies(u) { - if (!ALL_TARGET_CIDS.length) return; - const current = u.allClientIds || []; - u.allClientIds = [...new Set([...current, ...ALL_TARGET_CIDS])].filter(Boolean); - if (!u.profiles) u.profiles = []; - for (const cid of ALL_TARGET_CIDS) { - if (!u.profiles.find(p => p.client_id === cid)) - u.profiles.push({ client_id: cid, company_name: cid, is_active_profile: false }); - } -} - module.exports = { enhanceImpersonation };