Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | export const dynamic = "force-dynamic"; /** * Security Overview API Route * * Provides security overview metrics for the admin dashboard. * GET - Get security overview metrics */ import { NextRequest, NextResponse } from "next/server"; import { withAdmin, withErrorHandling, successResponse, ApiSuccessResponse, ApiErrorResponse, } from "@/lib/api"; import { getRecentSecurityEvents, getSecurityEventCounts, getBlockedIps, getFailedLoginStats, } from "@/lib/security/security-logger"; interface SecurityOverviewResponse { summary: { totalEvents: number; criticalEvents: number; highEvents: number; blockedIps: number; failedLogins: number; }; eventCounts: Record<string, number>; recentEvents: Array<{ id: string; type: string; severity: string; ipAddress: string; timestamp: Date; userId: number | null; }>; topFailedIps: Array<{ ipAddress: string; count: number; }>; blockedIpsList: Array<{ id: string; ipAddress: string; reason: string; expiresAt: Date; }>; } /** * GET /api/admin/security/overview * Get security overview data */ async function handleGet( request: NextRequest ): Promise< NextResponse<ApiSuccessResponse<SecurityOverviewResponse> | ApiErrorResponse> > { const { searchParams } = new URL(request.url); const hoursBack = parseInt(searchParams.get("hours") || "24", 10); const since = new Date(Date.now() - hoursBack * 60 * 60 * 1000); const [eventCounts, recentEvents, blockedIpsList, failedLoginStats] = await Promise.all([ getSecurityEventCounts(since), getRecentSecurityEvents({ limit: 20, since }), getBlockedIps(), getFailedLoginStats(since), ]); // Calculate summary const criticalCount = eventCounts["CRITICAL"] || 0; const highCount = eventCounts["HIGH"] || 0; const failedLoginCount = eventCounts["LOGIN_FAILURE"] || 0; const totalEvents = Object.values(eventCounts).reduce( (sum, count) => sum + count, 0 ); return successResponse({ summary: { totalEvents, criticalEvents: criticalCount, highEvents: highCount, blockedIps: blockedIpsList.length, failedLogins: failedLoginCount, }, eventCounts, recentEvents: recentEvents.map((e) => ({ id: e.id, type: e.type, severity: e.severity, ipAddress: e.ipAddress, timestamp: e.timestamp, userId: e.userId, })), topFailedIps: failedLoginStats.map((s) => ({ ipAddress: s.ipAddress, count: s._count.ipAddress, })), blockedIpsList: blockedIpsList.map((ip) => ({ id: ip.id, ipAddress: ip.ipAddress, reason: ip.reason, expiresAt: ip.expiresAt, })), }); } export const GET = withErrorHandling(withAdmin(handleGet)); |