Re_Backend/src/routes/antivirus.routes.ts

167 lines
4.4 KiB
TypeScript

/**
* Antivirus Admin Routes
* Admin endpoints for ClamAV management and audit logs.
*/
import { Router, Request, Response } from 'express';
import { authenticateToken } from '../middlewares/auth.middleware';
import { requireAdmin } from '../middlewares/authorization.middleware';
import { asyncHandler } from '../middlewares/errorHandler.middleware';
import {
getToggleStatus,
setToggleStatus,
getToggleHistory,
} from '../services/clamav/clamavToggleManager';
import { pingDaemon } from '../services/clamav/clamavScanWrapper';
import {
readAuditLogs,
getAuditStats,
exportAuditLogsCSV,
logSecurityEvent,
SecurityEventType,
} from '../services/logging/securityEventLogger';
const router = Router();
// All routes require admin authentication
router.use(authenticateToken, requireAdmin);
/**
* GET /api/v1/antivirus/clamav-status
* Get ClamAV toggle status, daemon health, and recent toggle history
*/
router.get(
'/clamav-status',
asyncHandler(async (_req: Request, res: Response) => {
const toggleStatus = getToggleStatus();
const daemonStatus = await pingDaemon();
const recentHistory = getToggleHistory(10);
res.json({
success: true,
toggle: toggleStatus,
daemon: daemonStatus,
recentHistory,
});
})
);
/**
* POST /api/v1/antivirus/clamav-toggle
* Enable or disable ClamAV scanning
* Body: { enabled: boolean, reason: string }
*/
router.post(
'/clamav-toggle',
asyncHandler(async (req: Request, res: Response) => {
const { enabled, reason } = req.body;
if (typeof enabled !== 'boolean') {
res.status(400).json({
success: false,
message: '"enabled" must be a boolean',
});
return;
}
if (!reason || typeof reason !== 'string') {
res.status(400).json({
success: false,
message: '"reason" is required',
});
return;
}
const userId = (req as any).user?.id || (req as any).user?.email || 'unknown';
const result = setToggleStatus(enabled, userId, reason);
// Log the admin action
logSecurityEvent(SecurityEventType.CLAMAV_TOGGLE_CHANGED, {
enabled,
reason,
changedBy: userId,
}, userId);
res.json({
success: true,
message: `ClamAV scanning ${enabled ? 'enabled' : 'disabled'}`,
state: result.state,
});
})
);
/**
* GET /api/v1/antivirus/audit-logs
* Search and paginate security audit logs
* Query params: eventType, severity, category, startDate, endDate, limit, offset
*/
router.get(
'/audit-logs',
asyncHandler(async (req: Request, res: Response) => {
const {
eventType,
severity,
category,
startDate,
endDate,
limit = '50',
offset = '0',
} = req.query;
const result = readAuditLogs({
eventType: eventType as string,
severity: severity as string,
category: category as string,
startDate: startDate as string,
endDate: endDate as string,
limit: parseInt(limit as string, 10),
offset: parseInt(offset as string, 10),
});
res.json({
success: true,
...result,
});
})
);
/**
* GET /api/v1/antivirus/audit-logs/export
* Export filtered audit logs as CSV
*/
router.get(
'/audit-logs/export',
asyncHandler(async (req: Request, res: Response) => {
const { eventType, severity, startDate, endDate } = req.query;
const csv = exportAuditLogsCSV({
eventType: eventType as string,
severity: severity as string,
startDate: startDate as string,
endDate: endDate as string,
});
res.setHeader('Content-Type', 'text/csv');
res.setHeader('Content-Disposition', `attachment; filename=audit-logs-${new Date().toISOString().split('T')[0]}.csv`);
res.send(csv);
})
);
/**
* GET /api/v1/antivirus/audit-stats
* Get audit log statistics
*/
router.get(
'/audit-stats',
asyncHandler(async (_req: Request, res: Response) => {
const stats = getAuditStats();
res.json({
success: true,
stats,
});
})
);
export default router;