- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
/**
|
|
* Audit Middleware
|
|
*
|
|
* Automatically logs audit events for all requests
|
|
* Per DoD/MilSpec requirements (NIST SP 800-53: AU-2, AU-3)
|
|
*/
|
|
|
|
import { FastifyRequest, FastifyReply } from 'fastify'
|
|
import { logAuditEvent, logAuthentication, logDataAccess } from '../services/audit-logger'
|
|
import { logger } from '../lib/logger'
|
|
|
|
/**
|
|
* Audit middleware - logs all requests for audit trail
|
|
*/
|
|
export async function auditMiddleware(
|
|
request: FastifyRequest,
|
|
reply: FastifyReply
|
|
): Promise<void> {
|
|
// Skip audit logging for health checks and WebSocket upgrades
|
|
if (request.url === '/health' || request.url === '/graphql-ws') {
|
|
return
|
|
}
|
|
|
|
const user = (request as any).user
|
|
const startTime = Date.now()
|
|
|
|
// Log request
|
|
try {
|
|
// Determine event type based on request
|
|
if (request.url === '/graphql') {
|
|
// GraphQL request - log based on operation
|
|
const body = request.body as any
|
|
const operation = body?.operationName || 'UNKNOWN'
|
|
|
|
await logAuditEvent({
|
|
eventType: 'DATA_ACCESS',
|
|
result: reply.statusCode < 400 ? 'SUCCESS' : 'FAILURE',
|
|
userId: user?.id,
|
|
userName: user?.name,
|
|
userRole: user?.role,
|
|
ipAddress: request.ip,
|
|
userAgent: request.headers['user-agent'],
|
|
action: `GRAPHQL_${operation}`,
|
|
details: {
|
|
query: body?.query?.substring(0, 200), // Log first 200 chars of query
|
|
variables: body?.variables ? 'PRESENT' : 'NONE', // Don't log full variables
|
|
},
|
|
})
|
|
} else {
|
|
// Regular HTTP request
|
|
await logAuditEvent({
|
|
eventType: 'DATA_ACCESS',
|
|
result: reply.statusCode < 400 ? 'SUCCESS' : 'FAILURE',
|
|
userId: user?.id,
|
|
userName: user?.name,
|
|
userRole: user?.role,
|
|
ipAddress: request.ip,
|
|
userAgent: request.headers['user-agent'],
|
|
action: `${request.method} ${request.url}`,
|
|
details: {
|
|
statusCode: reply.statusCode,
|
|
responseTime: Date.now() - startTime,
|
|
},
|
|
})
|
|
}
|
|
} catch (error) {
|
|
// Don't fail the request if audit logging fails, but log the error
|
|
logger.error('Failed to log audit event', { error, request: request.url })
|
|
}
|
|
}
|
|
|