Linking backend data to frontend

This commit is contained in:
iv_vuytsik
2025-10-15 19:49:19 +03:00
parent ea1f50c1b8
commit 2b19ed246b
28 changed files with 959 additions and 385 deletions

View File

@@ -0,0 +1,109 @@
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 }
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 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)
let backendRes = await fetch(`${backendUrl}/account/get-reports/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ report_format: finalFormat, hours: finalHours }),
})
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' },
})
}
}