// ═══════════════════════════════════════════════════════════════════════════════ // V2 — тестовый роутер (монтируется в server.js как /v2) // Только: вход через Keycloak → вывод ответа IAM на экран // ═══════════════════════════════════════════════════════════════════════════════ 'use strict'; const express = require('express'); const config = require('./src/config'); const auth = require('./src/auth'); const oidcConfig = { baseUrl: config.kcBaseUrl, clientId: config.kcClientId, clientSecret: config.kcClientSecret, redirectUri: config.appUrl.replace(/\/$/, '') + '/v2/callback', }; /** * createV2Router — создаёт роутер для монтирования в основной server.js. * Сессия используется общая, но ключи — с префиксом v2_ чтобы не пересекаться. */ function createV2Router() { const router = express.Router(); // ── GET /v2/ — главная (вывод IAM-данных) ─────────────────────────────── router.get('/', (req, res) => { if (!req.session.v2_user) { return res.redirect('/v2/login'); } const u = req.session.v2_user; res.send(`
Email: ${u.email}
clientId: ${u.clientId} (активная компания)
Компания: ${u.companyName}
isAdmin: ${u.isAdmin}
ФИО: ${u.fio || '—'}
Компаний: ${u.allClientIds ? u.allClientIds.length : 0} — ${(u.allClientIds || []).join(', ')}
${u.isImpersonated ? `⚠️ Имперсонация: ${u.originalUserEmail} → ${u.email}
` : ''}${JSON.stringify(u, null, 2)}
`);
});
// ── GET /v2/login — редирект на Keycloak ────────────────────────────────
router.get('/login', (req, res) => {
if (req.session.v2_user) return res.redirect('/v2/');
const state = auth.generateState();
req.session.v2_oidcState = state;
const url = auth.buildAuthUrl({ ...oidcConfig, state });
console.log('[v2] → Keycloak');
res.redirect(url);
});
// ── GET /v2/callback — Keycloak возвращает пользователя ──────────────────
router.get('/callback', async (req, res) => {
const { code, state } = req.query;
if (!state || state !== req.session.v2_oidcState) {
return res.status(403).send('Invalid state — possible CSRF attack');
}
delete req.session.v2_oidcState;
if (!code) {
return res.status(400).send('Missing authorization code');
}
try {
console.log('[v2] Exchanging code...');
const result = await auth.login(code, oidcConfig, config.iamUrl);
req.session.v2_user = result.sessionUser;
req.session.v2_token = result.token;
req.session.v2_idToken = result.idToken;
console.log('[v2] ✅ Login OK:', result.sessionUser.email, result.sessionUser.clientId);
res.redirect('/v2/');
} catch (err) {
console.error('[v2] ❌ Login failed:', err.message);
res.status(500).send(`
${err.message}\n\n${err.stack || ''}
`);
}
});
// ── GET /v2/logout ───────────────────────────────────────────────────────
router.get('/logout', (req, res) => {
delete req.session.v2_user;
delete req.session.v2_token;
delete req.session.v2_idToken;
res.redirect('/v2/');
});
return router;
}
module.exports = { createV2Router };