26 lines
1.5 KiB
TypeScript
26 lines
1.5 KiB
TypeScript
import type { APIRoute } from "astro";
|
|
|
|
const base = process.env.API_INTERNAL_URL || import.meta.env.API_INTERNAL_URL || "http://localhost:8000";
|
|
|
|
export const POST: APIRoute = async ({ request, redirect, cookies }) => {
|
|
const form = await request.formData();
|
|
const reportId = String(form.get("report_id") || "");
|
|
const screenshot = form.get("screenshot");
|
|
const cookieName = `rf4-upload-${reportId}`;
|
|
const uploadToken = cookies.get(cookieName)?.value;
|
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(reportId) || !uploadToken || !(screenshot instanceof File) || screenshot.size === 0) return redirect(`/report?state=screenshot_error&report_id=${encodeURIComponent(reportId)}`, 303);
|
|
try {
|
|
const upload = new FormData(); upload.set("screenshot", screenshot);
|
|
const response = await fetch(`${base}/api/v1/catch-reports/${reportId}/screenshot`, { method: "POST", headers:{"X-Upload-Token":uploadToken}, body: upload, signal: AbortSignal.timeout(60_000) });
|
|
if (response.ok) {
|
|
cookies.delete(cookieName, {path:"/"});
|
|
cookies.delete("rf4-idempotency-key", {path:"/"});
|
|
}
|
|
return redirect(response.ok ? "/report?state=screenshot_sent" : `/report?state=screenshot_error&report_id=${encodeURIComponent(reportId)}`, 303);
|
|
} catch {
|
|
// The report already exists and the upload can have reached the API before
|
|
// the timeout. Keep the recovery form visible; the API makes a retry safe.
|
|
return redirect(`/report?state=screenshot_error&report_id=${encodeURIComponent(reportId)}`, 303);
|
|
}
|
|
};
|