import { NextResponse } from "next/server"; import { getSessionUser } from "@/lib/session"; import { getInvoiceByNumberForOrg, getInvoicePdf } from "@/lib/db"; /** * GET /api/billing/invoices/[invoiceNumber]/pdf * * Customer-facing PDF download. Same Uint8Array.from() variance * fix as the admin route — see /api/admin/billing/invoices/[id]/pdf * for the rationale. * * Authorization: looks up the invoice by number with org scope * baked into the query, then re-fetches the PDF blob by id. A * customer can't probe another org's invoice numbers — they get * 404 either way. */ export async function GET( _request: Request, { params }: { params: Promise<{ invoiceNumber: string }> } ) { const user = await getSessionUser(); if (!user) { return new NextResponse("Unauthorized", { status: 401 }); } const { invoiceNumber } = await params; const detail = await getInvoiceByNumberForOrg(invoiceNumber, user.orgId); if (!detail) { return new NextResponse("Not found", { status: 404 }); } const pdf = await getInvoicePdf(detail.invoice.id); if (!pdf) { return new NextResponse("PDF not available", { status: 404 }); } const body = Uint8Array.from(pdf.data); return new NextResponse(body, { status: 200, headers: { "Content-Type": "application/pdf", "Content-Disposition": `inline; filename="${pdf.filename}"`, "Cache-Control": "private, max-age=0, must-revalidate", }, }); }