const express = require('express'); const cookieParser = require('cookie-parser'); const path = require('path'); require('dotenv').config(); const { checkConnection } = require('./src/db'); const { initAuth } = require('./src/auth'); const q = require('./src/queries'); const app = express(); const PORT = process.env.PORT || 3000; app.set('view engine', 'ejs'); app.set('views', path.join(__dirname, 'views')); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.urlencoded({ extended: true, limit: '32kb' })); app.use(cookieParser()); const MOCK_USERS = [ { id: 'admin', label: 'Администратор (WZ01112)', role: 'admin', clientId: 'WZ01112', companyId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', companyName: 'Nubes Admin', email: 'admin@nubes.ru' }, { id: 'test', label: 'Тест (WZ01325)', role: 'user', clientId: 'WZ01325', companyId: '3e64aac6-dcfc-4082-88dc-da19c86555a5', companyName: 'Тест', email: 'tazet@narod.ru' }, { id: 'client2', label: 'Компания 2 (WZ02001)', role: 'user', clientId: 'WZ02001', companyId: '11111111-2222-3333-4444-555555555555', companyName: 'Вторая Компания', email: 'user2@example.com' }, ]; async function start() { const auth = await initAuth(); app.get('/healthz', (req, res) => res.send('OK')); if (auth.jwksHandler) app.get('/.well-known/jwks.json', auth.jwksHandler); app.get('/login', (req, res) => res.render('login', { users: MOCK_USERS, error: req.query.error || null })); app.post('/login', async (req, res) => { const user = MOCK_USERS.find(u => u.id === req.body.user); if (!user) return res.redirect('/login?error=' + encodeURIComponent('Пользователь не найден')); try { const token = await auth.issue({ clientId: user.clientId, companyId: user.companyId, companyName: user.companyName, email: user.email }); res.cookie('jwt', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: 24 * 60 * 60 * 1000 }); res.redirect(req.query.returnTo || '/'); } catch (e) { res.redirect('/login?error=' + encodeURIComponent('Ошибка выпуска токена')); } }); app.get('/logout', (req, res) => { res.clearCookie('jwt'); res.redirect('/login'); }); app.use(auth.middleware); app.get('/', async (req, res) => { const { clientId, companyName } = req.user; try { const company = await q.getOrCreateCompany(clientId, companyName); const limit = await q.getLimit(company); const entries = await q.listEntries(company.id); res.render('index', { entries, limit, used: entries.length, user: req.user, error: req.query.error || null, message: req.query.message || null, wasNormalized: req.query.wasNormalized === '1' }); } catch (e) { res.render('index', { entries: [], limit: 15, used: 0, user: req.user, error: 'Ошибка загрузки', message: null, wasNormalized: false }); } }); app.post('/add', async (req, res) => { const { value, comment } = req.body; const { clientId, companyName, email } = req.user; try { const company = await q.getOrCreateCompany(clientId, companyName); const result = await q.createEntry(company.id, value, comment, email); const message = result.wasNormalized ? `Адрес нормализован в ${result.entry.value_cidr}` : 'Добавлено'; const wasNormalized = result.wasNormalized ? '1' : '0'; res.redirect('/?message=' + encodeURIComponent(message) + '&wasNormalized=' + wasNormalized); } catch (e) { res.redirect('/?error=' + encodeURIComponent(e.message)); } }); app.post('/delete/:id', async (req, res) => { const { clientId, companyName, email } = req.user; try { const company = await q.getOrCreateCompany(clientId, companyName); await q.deleteEntry(req.params.id, company.id, email); res.redirect('/'); } catch (e) { res.redirect('/?error=' + encodeURIComponent(e.message)); } }); app.get('/export', async (req, res) => { try { const { clientId, companyName } = req.user; const company = await q.getOrCreateCompany(clientId, companyName); const cidrs = await q.getExportCIDRs(company.id); res.setHeader('Content-Type', 'text/plain; charset=utf-8'); res.send(cidrs.join('\n') + '\n'); } catch (e) { res.status(500).send('Export error'); } }); checkConnection().then(() => console.log('DB connected')).catch(e => console.error('DB not ready:', e.message)); app.listen(PORT, () => console.log('Server on port ' + PORT)); } start().catch(e => { console.error('Startup error:', e); process.exit(1); });