import express from 'express'; import { WebProofService } from '../services/WebProofService'; import { prisma } from '../prismaClient'; import * as path from 'path'; import * as fs from 'fs'; const router = express.Router(); const webProofService = new WebProofService(); // Criar nova sessão de captura web router.post('/sessions', async (req, res) => { try { const { sessionId, targetUrl, description, metadata, environment, screenshots } = req.body; // Validar dados de entrada if (!sessionId || !targetUrl || !metadata || !environment) { return res.status(400).json({ error: 'Dados obrigatórios não fornecidos', required: ['sessionId', 'targetUrl', 'metadata', 'environment'] }); } // Validar URL try { new URL(targetUrl); } catch { return res.status(400).json({ error: 'URL inválida fornecida' }); } // Coletar informações de rede do cliente const clientInfo = { ip: req.headers['x-forwarded-for']?.toString().split(',')[0].trim() || req.ip || req.socket.remoteAddress || '127.0.0.1', port: req.socket.remotePort || 0, userAgent: req.headers['user-agent'] || '', timestamp: new Date().toISOString() }; // Processar sessão de captura const result = await webProofService.processWebCapture({ sessionId, targetUrl, description, metadata: { ...metadata, clientInfo, serverInfo: { hostname: require('os').hostname(), nodeVersion: process.version, timestamp: new Date().toISOString() } }, environment, screenshots: screenshots || [] }); res.json({ success: true, sessionId: result.id, status: result.status, message: 'Sessão de captura processada com sucesso' }); } catch (error) { console.error('Erro ao processar sessão de captura:', error); res.status(500).json({ error: 'Falha ao processar sessão de captura', details: error.message }); } }); // Obter status da sessão router.get('/sessions/:sessionId/status', async (req, res) => { try { const { sessionId } = req.params; const session = await prisma.webProofSession.findUnique({ where: { sessionId } }); if (!session) { return res.status(404).json({ error: 'Sessão não encontrada' }); } res.json({ sessionId: session.sessionId, status: session.status, targetUrl: session.targetUrl, description: session.description, createdAt: session.createdAt, updatedAt: session.updatedAt, reportPath: session.reportPath, error: session.error }); } catch (error) { console.error('Erro ao buscar status da sessão:', error); res.status(500).json({ error: 'Erro ao buscar status da sessão' }); } }); // Obter timestamp confiável router.get('/trusted-timestamp', async (req, res) => { try { // Simular obtenção de timestamp de autoridade certificadora const trustedTimestamp = await webProofService.getTrustedTimestamp(); res.json({ timestamp: trustedTimestamp.timestamp, authority: trustedTimestamp.authority, signature: trustedTimestamp.signature }); } catch (error) { console.error('Erro ao obter timestamp confiável:', error); res.status(500).json({ error: 'Erro ao obter timestamp confiável', fallback: new Date().toISOString() }); } }); // Obter informações do cliente router.get('/client-info', async (req, res) => { try { const clientInfo = { ip: req.headers['x-forwarded-for']?.toString().split(',')[0].trim() || req.ip || req.socket.remoteAddress || '127.0.0.1', port: req.socket.remotePort || 0, userAgent: req.headers['user-agent'] || '', timestamp: new Date().toISOString(), headers: { 'x-forwarded-for': req.headers['x-forwarded-for'], 'user-agent': req.headers['user-agent'], 'accept-language': req.headers['accept-language'] } }; res.json(clientInfo); } catch (error) { console.error('Erro ao obter informações do cliente:', error); res.status(500).json({ error: 'Erro ao obter informações do cliente', fallback: { ip: '127.0.0.1', port: 0, timestamp: new Date().toISOString() } }); } }); // Verificar autenticidade de captura web com detalhes aprimorados router.get('/verify/:sessionId', async (req, res) => { try { const { sessionId } = req.params; if (!sessionId || typeof sessionId !== 'string') { return res.status(400).json({ verified: false, error: 'SessionId inválido' }); } const verification = await webProofService.verifyWebCapture(sessionId); res.json({ verified: verification.verified, sessionId, sessionValid: verification.sessionValid || false, contentValid: verification.contentValid || false, timestampValid: verification.timestampValid || false, verificationDetails: verification.details, timestamp: new Date().toISOString() }); } catch (error) { console.error('Erro ao verificar captura:', error); res.status(500).json({ verified: false, sessionValid: false, contentValid: false, timestampValid: false, error: 'Erro ao verificar captura web' }); } }); // Baixar relatório com validação aprimorada router.get('/relatorio/:sessionId', async (req, res) => { try { const { sessionId } = req.params; if (!sessionId || typeof sessionId !== 'string') { return res.status(400).json({ error: 'SessionId inválido' }); } const session = await prisma.webProofSession.findUnique({ where: { sessionId } }); if (!session) { return res.status(404).json({ error: 'Sessão não encontrada' }); } if (session.status !== 'CONCLUIDO') { return res.status(400).json({ error: 'Relatório ainda não está disponível', status: session.status }); } const reportPath = path.join(process.cwd(), 'storage', 'web-proofs', `${sessionId}_report.pdf`); if (!fs.existsSync(reportPath)) { console.error('Arquivo de relatório não encontrado:', reportPath); return res.status(404).json({ error: 'Arquivo do relatório não encontrado' }); } res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', `inline; filename="captura_web_${sessionId}_relatorio.pdf"`); res.setHeader('Cache-Control', 'public, max-age=3600'); // Cache de 1 hora const fileStream = fs.createReadStream(reportPath); fileStream.on('error', (error) => { console.error('Erro ao ler arquivo de relatório:', error); if (!res.headersSent) { res.status(500).json({ error: 'Erro ao ler arquivo de relatório' }); } }); fileStream.pipe(res); } catch (error) { console.error('Erro ao servir relatório:', error); if (!res.headersSent) { res.status(500).json({ error: 'Erro ao gerar relatório' }); } } }); // Listar sessões com paginação router.get('/admin/sessions', async (req, res) => { try { const page = parseInt(req.query.page as string) || 1; const limit = parseInt(req.query.limit as string) || 100; const offset = (page - 1) * limit; const [sessions, total] = await Promise.all([ prisma.webProofSession.findMany({ orderBy: { createdAt: 'desc' }, skip: offset, take: limit, select: { sessionId: true, targetUrl: true, description: true, status: true, createdAt: true, processedAt: true, error: true } }), prisma.webProofSession.count() ]); res.json({ sessions, pagination: { page, limit, total, totalPages: Math.ceil(total / limit) } }); } catch (error) { console.error('Erro ao listar sessões:', error); res.status(500).json({ error: 'Erro ao listar sessões' }); } }); export default router;