From 6032a574a93bde71331503b1cde79c83aaa99d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 15 Jun 2026 10:14:16 +0400 Subject: [PATCH] =?UTF-8?q?v0.6.4:=20=D0=B0=D0=B2=D1=82=D0=BE-=D0=B8=D0=BC?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D1=86=D0=B8=D1=8F=20?= =?UTF-8?q?(ORIGINAL=E2=86=92TARGET)=20+=20ADMIN=5FEMAIL?= 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 | 54 +++++++++++++++++++++++------------ v2/src/router/index.js | 3 +- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 858bcab..fcbbfe7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.6.3", + "version": "0.6.4", "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 f9fcbbd..bc496ed 100644 --- a/v2/src/config/index.js +++ b/v2/src/config/index.js @@ -9,7 +9,7 @@ // ═══════════════════════════════════════════════════════════════════════════════ module.exports = { - version: '0.6.3', + version: '0.6.4', // ── 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 c7e5366..00f0bcf 100644 --- a/v2/src/impersonation/index.js +++ b/v2/src/impersonation/index.js @@ -1,32 +1,50 @@ // ═══════════════════════════════════════════════════════════════════════════════ -// V2 — Расширение имперсонации (отдельный модуль) +// V2 — Авто-имперсонация (отдельный модуль) // -// ЭТО: middleware — добавляет дополнительные компании имперсонируемому юзеру. -// НЕ: жёсткая логика в resolveContext или user/index.js. +// УСЛОВИЯ (все три должны быть заданы): +// IMPERSONATION_ORIGINAL = email юзера при входе (ntazetdinov@nubes.ru) +// IMPERSONATION_TARGET = в кого имперсонировать (tazet@narod.ru) +// IMPERSONATION_COMPANY = компания цели (WZ01325) // -// ENV: -// IMPERSONATION_TARGET — email юзера, которому добавляем компании -// IMPERSONATION_EXTRA_COMPANIES — W-номера через запятую (WZ01112,WZ03709) +// ОПЦИОНАЛЬНО: +// IMPERSONATION_EXTRA_COMPANIES = доп. компании через запятую (WZ01112) +// +// ЧТО ДЕЛАЕТ: +// Когда юзер с email === ORIGINAL входит → сессия подменяется: +// email → TARGET +// clientId → COMPANY +// allClientIds → [COMPANY, EXTRA_COMPANIES] +// isImpersonated → true +// originalUserEmail → ORIGINAL // ═══════════════════════════════════════════════════════════════════════════════ -const TARGET_EMAIL = process.env.IMPERSONATION_TARGET || ''; -const EXTRA_COMPANIES = (process.env.IMPERSONATION_EXTRA_COMPANIES || '') +const ORIGINAL = process.env.IMPERSONATION_ORIGINAL || ''; +const TARGET = process.env.IMPERSONATION_TARGET || ''; +const COMPANY = process.env.IMPERSONATION_COMPANY || ''; +const EXTRA = (process.env.IMPERSONATION_EXTRA_COMPANIES || '') .split(',').map(s => s.trim()).filter(Boolean); +// Все три обязательны +const ENABLED = ORIGINAL && TARGET && COMPANY; + function enhanceImpersonation(req, res, next) { - if (!TARGET_EMAIL) return next(); + if (!ENABLED) return next(); + const u = req.session && req.session.user; - if (!u || u.email !== TARGET_EMAIL) return next(); + if (!u || u.email !== ORIGINAL) return next(); - const current = u.allClientIds || [u.clientId || '']; - u.allClientIds = [...new Set([...current, ...EXTRA_COMPANIES])].filter(Boolean); + // Подмена сессии — авто-имперсонация + const allCids = [COMPANY, ...EXTRA]; + u.originalUserEmail = ORIGINAL; // кто реально вошёл + u.email = TARGET; // в кого имперсонируем + u.clientId = COMPANY; + u.activeClientId = COMPANY; + u.allClientIds = allCids; + u.isImpersonated = true; + u.companyName = COMPANY; + u.profiles = allCids.map(cid => ({ client_id: cid, company_name: cid })); - if (!u.profiles) u.profiles = []; - for (const cid of EXTRA_COMPANIES) { - if (!u.profiles.find(p => p.client_id === cid)) - u.profiles.push({ client_id: cid, company_name: cid, is_active_profile: false }); - } next(); } -module.exports = { enhanceImpersonation, TARGET_EMAIL, EXTRA_COMPANIES }; +module.exports = { enhanceImpersonation }; diff --git a/v2/src/router/index.js b/v2/src/router/index.js index a6d988a..888e7a4 100644 --- a/v2/src/router/index.js +++ b/v2/src/router/index.js @@ -35,12 +35,13 @@ function resolveContext(req, res, next) { // Имперсонация: админ действует от имени компании // u.originalUserEmail — реальный админ // u.impersonatedCompanyId — W-номер компании + const ADMIN_EMAIL = process.env.ADMIN_EMAIL || ''; const isImpersonated = !!(u.originalUserEmail && u.impersonatedCompanyId); req.email = isImpersonated ? u.originalUserEmail : (u.email || ''); req.clientId = isImpersonated ? u.impersonatedCompanyId : (u.activeClientId || u.clientId || ''); req.companyName = u.companyName || req.clientId; - req.isAdmin = !!(u.isAdmin && u.adminMode); + req.isAdmin = !!(u.isAdmin && u.adminMode) || (ADMIN_EMAIL && u.email === ADMIN_EMAIL); req.isImpersonated = isImpersonated; req.impersonatedBy = isImpersonated ? u.email : null; req.allClientIds = u.allClientIds || [req.clientId];