v0.5.115: тестовая имперсонация — полная подмена данных через ENV
This commit is contained in:
@@ -1,40 +1,77 @@
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
// V2 — Расширение имперсонации (отдельный модуль)
|
// V2 — Имперсонация (IAM + тестовый режим через ENV)
|
||||||
//
|
//
|
||||||
// ЭТО: middleware — добавляет дополнительные компании админу.
|
// ЭТО: middleware — имитирует IAM-имперсонацию для тестов.
|
||||||
// НЕ: жёсткая логика в resolveContext или user/index.js.
|
// НЕ: жёсткая логика в resolveContext или user/index.js.
|
||||||
//
|
//
|
||||||
|
// ТЕСТОВЫЙ РЕЖИМ (если задан IMPERSONATION_TARGET):
|
||||||
|
// При входе IMPERSONATION_ORIGINAL все данные сессии заменяются на TARGET.
|
||||||
|
// Полная имитация IAM-имперсонации: email, profiles, clientId — всё от таргета.
|
||||||
|
//
|
||||||
// ENV:
|
// ENV:
|
||||||
// IMPERSONATION_ORIGINAL — email админа, который имперсонирует
|
// IMPERSONATION_ORIGINAL — email админа (кто имперсонирует)
|
||||||
// IMPERSONATION_COMPANY — W-номер компании имперсонируемого
|
// IMPERSONATION_TARGET — email юзера (кого имперсонируют) ← тест
|
||||||
|
// IMPERSONATION_COMPANY — W-номер основной компании таргета
|
||||||
// IMPERSONATION_EXTRA_COMPANIES — доп. W-номера через запятую
|
// IMPERSONATION_EXTRA_COMPANIES — доп. W-номера через запятую
|
||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
const ORIGINAL_EMAIL = process.env.IMPERSONATION_ORIGINAL || '';
|
const ORIGINAL_EMAIL = process.env.IMPERSONATION_ORIGINAL || '';
|
||||||
const EXTRA_COMPANIES = [
|
const TARGET_EMAIL = process.env.IMPERSONATION_TARGET || '';
|
||||||
process.env.IMPERSONATION_COMPANY || '',
|
const MAIN_COMPANY = process.env.IMPERSONATION_COMPANY || '';
|
||||||
...(process.env.IMPERSONATION_EXTRA_COMPANIES || '').split(',').map(s => s.trim())
|
const EXTRA_COMPANIES = (process.env.IMPERSONATION_EXTRA_COMPANIES || '')
|
||||||
].filter(Boolean);
|
.split(',').map(s => s.trim()).filter(Boolean);
|
||||||
|
const ALL_TARGET_CIDS = [...new Set([MAIN_COMPANY, ...EXTRA_COMPANIES].filter(Boolean))];
|
||||||
|
|
||||||
function enhanceImpersonation(req, res, next) {
|
function enhanceImpersonation(req, res, next) {
|
||||||
if (!ORIGINAL_EMAIL) return next();
|
|
||||||
const u = req.session && req.session.user;
|
const u = req.session && req.session.user;
|
||||||
if (!u) return next();
|
if (!u) return next();
|
||||||
|
|
||||||
// Админ имперсонирует: его originalUserEmail совпадает с ORIGINAL_EMAIL
|
// ── IAM-имперсонация (уже есть в сессии) — просто добавляем компании ──
|
||||||
// или он сам залогинен под ORIGINAL_EMAIL
|
if (u.isImpersonated && u.originalUserEmail === ORIGINAL_EMAIL) {
|
||||||
const isOriginal = u.email === ORIGINAL_EMAIL || u.originalUserEmail === ORIGINAL_EMAIL;
|
addExtraCompanies(u);
|
||||||
if (!isOriginal) return next();
|
return next();
|
||||||
|
|
||||||
const current = u.allClientIds || [u.clientId || ''];
|
|
||||||
u.allClientIds = [...new Set([...current, ...EXTRA_COMPANIES])].filter(Boolean);
|
|
||||||
|
|
||||||
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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Тестовый режим: полная подмена данных ───────────────────────────
|
||||||
|
if (TARGET_EMAIL && u.email === ORIGINAL_EMAIL) {
|
||||||
|
// Сохраняем isAdmin от оригинала
|
||||||
|
const wasAdmin = u.isAdmin || (u.allClientIds || []).includes('WZ01112') || u.clientId === 'WZ01112';
|
||||||
|
|
||||||
|
// Подменяем ВСЕ данные на таргета (как делает IAM)
|
||||||
|
u.email = TARGET_EMAIL;
|
||||||
|
u.clientId = MAIN_COMPANY || u.clientId;
|
||||||
|
u.activeClientId = MAIN_COMPANY || u.clientId;
|
||||||
|
u.allClientIds = ALL_TARGET_CIDS;
|
||||||
|
u.companyName = MAIN_COMPANY;
|
||||||
|
u.isAdmin = wasAdmin; // админство сохраняется
|
||||||
|
u.isImpersonated = true;
|
||||||
|
u.originalUserEmail = ORIGINAL_EMAIL;
|
||||||
|
u.originalUserFullName = u.fio ? (u.fio.fullName || '') : '';
|
||||||
|
u.fio = null; // фио таргета неизвестно
|
||||||
|
|
||||||
|
// Профили таргета (имитация)
|
||||||
|
u.profiles = ALL_TARGET_CIDS.map(cid => ({
|
||||||
|
client_id: cid,
|
||||||
|
company_name: cid,
|
||||||
|
is_active_profile: cid === MAIN_COMPANY,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Не имперсонация — ничего не делаем ──────────────────────────────
|
||||||
next();
|
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 };
|
module.exports = { enhanceImpersonation };
|
||||||
|
|||||||
Reference in New Issue
Block a user