116 lines
4.6 KiB
TypeScript
116 lines
4.6 KiB
TypeScript
import { getServerSession } from 'next-auth'
|
|
import { authOptions } from '@/lib/auth'
|
|
import { NextRequest } from 'next/server'
|
|
import { getToken } from 'next-auth/jwt'
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const session = await getServerSession(authOptions)
|
|
|
|
const authHeader = req.headers.get('authorization') || req.headers.get('Authorization')
|
|
const bearer = authHeader && authHeader.toLowerCase().startsWith('bearer ') ? authHeader.slice(7) : undefined
|
|
|
|
const secret = process.env.NEXTAUTH_SECRET
|
|
const token = await getToken({ req, secret }).catch(() => null)
|
|
|
|
let accessToken = session?.accessToken || bearer || (token as any)?.accessToken
|
|
const refreshToken = session?.refreshToken || (token as any)?.refreshToken
|
|
|
|
if (!accessToken && refreshToken) {
|
|
try {
|
|
const refreshRes = await fetch(`${process.env.BACKEND_URL}/auth/refresh/`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ refresh: refreshToken }),
|
|
})
|
|
if (refreshRes.ok) {
|
|
const refreshed = await refreshRes.json()
|
|
accessToken = refreshed.access
|
|
}
|
|
} catch {}
|
|
}
|
|
|
|
if (!accessToken) {
|
|
return new Response(JSON.stringify({ success: false, error: 'Unauthorized' }), {
|
|
status: 401,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
const backendUrl = process.env.BACKEND_URL
|
|
if (!backendUrl) {
|
|
return new Response(JSON.stringify({ success: false, error: 'BACKEND_URL is not configured' }), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
const body = await req.json().catch(() => ({ })) as { format?: 'csv' | 'pdf', hours?: number, detector_ids?: number[] }
|
|
const reportFormat = (body.format || '').toLowerCase()
|
|
|
|
const url = new URL(req.url)
|
|
const qpFormat = (url.searchParams.get('format') || '').toLowerCase()
|
|
const qpHoursRaw = url.searchParams.get('hours')
|
|
const qpDetectorIds = url.searchParams.get('detector_ids')
|
|
const qpHours = qpHoursRaw ? Number(qpHoursRaw) : undefined
|
|
const finalFormat = reportFormat || qpFormat
|
|
const finalHours = typeof body.hours === 'number' ? body.hours : (typeof qpHours === 'number' && !Number.isNaN(qpHours) ? qpHours : 168)
|
|
const finalDetectorIds = body.detector_ids || (qpDetectorIds ? qpDetectorIds.split(',').map(id => Number(id)) : undefined)
|
|
|
|
const requestBody: any = { report_format: finalFormat, hours: finalHours }
|
|
if (finalDetectorIds && finalDetectorIds.length > 0) {
|
|
requestBody.detector_ids = finalDetectorIds
|
|
}
|
|
|
|
let backendRes = await fetch(`${backendUrl}/account/get-reports/`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
Authorization: `Bearer ${accessToken}`,
|
|
},
|
|
body: JSON.stringify(requestBody),
|
|
})
|
|
|
|
if (!backendRes.ok && backendRes.status === 404) {
|
|
backendRes = await fetch(`${backendUrl}/account/get-report/`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
Authorization: `Bearer ${accessToken}`,
|
|
},
|
|
body: JSON.stringify({ report_format: finalFormat, hours: finalHours }),
|
|
})
|
|
}
|
|
|
|
if (!backendRes.ok) {
|
|
const errText = await backendRes.text().catch(() => '')
|
|
const contentType = backendRes.headers.get('Content-Type') || 'text/plain'
|
|
return new Response(errText || 'Error generating report', {
|
|
status: backendRes.status,
|
|
headers: {
|
|
'Content-Type': contentType,
|
|
},
|
|
})
|
|
}
|
|
|
|
const arrayBuffer = await backendRes.arrayBuffer()
|
|
const contentType = backendRes.headers.get('Content-Type') || 'application/octet-stream'
|
|
const contentDisposition = backendRes.headers.get('Content-Disposition') || backendRes.headers.get('content-disposition')
|
|
|
|
const headers: Record<string, string> = { 'Content-Type': contentType }
|
|
if (contentDisposition) {
|
|
headers['Content-Disposition'] = contentDisposition
|
|
} else if (finalFormat) {
|
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').replace(/T/g, '_')
|
|
headers['Content-Disposition'] = `attachment; filename="alerts_report_${timestamp}.${finalFormat}"`
|
|
}
|
|
|
|
return new Response(arrayBuffer, { status: 200, headers })
|
|
} catch (error) {
|
|
console.error('Error proxying report export:', error)
|
|
return new Response(JSON.stringify({ success: false, error: 'Failed to export report' }), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
} |