add new proofsystem
This commit is contained in:
1 parent
a63aaeb655
commit
2399cb1f2d
11 files changed
+2009
-6
No files matched your search
@@ -0,0 +1,296 @@
|
||||
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;
|
||||
Reference in new issue
Block a user