diff --git a/src/pages/api/sentryProxy.ts b/src/pages/api/sentryProxy.ts new file mode 100644 index 00000000..1c59e9b8 --- /dev/null +++ b/src/pages/api/sentryProxy.ts @@ -0,0 +1,42 @@ +import { NextApiRequest, NextApiResponse } from "next"; + +const SENTRY_HOST = "o4504768725909504.ingest.us.sentry.io"; +const SENTRY_PROJECT_IDS = ["4508485201231872"]; + +export const route = "/api/sentry"; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + if (req.method !== "POST") { + return res.status(405).json({ error: "Method not allowed" }); + } + + try { + const requestBody = req.body; + const [headerPiece] = requestBody.split("\n"); + const header = JSON.parse(headerPiece); + const dsn = new URL(header["dsn"]); + const project_id = dsn.pathname?.replace("/", ""); + + if (dsn.hostname !== SENTRY_HOST) { + throw new Error(`Invalid sentry hostname: ${dsn.hostname}`); + } + + if (!project_id || !SENTRY_PROJECT_IDS.includes(project_id)) { + throw new Error(`Invalid sentry project id: ${project_id}`); + } + + const upstream_sentry_url = `https://${SENTRY_HOST}/api/${project_id}/envelope/`; + await fetch(upstream_sentry_url, { + method: "POST", + body: requestBody, + headers: { + "Content-Type": req.headers["content-type"] || "application/octet-stream", + }, + }); + + res.status(200).json({}); + } catch (e) { + console.error("Error tunneling to Sentry:", e); + res.status(500).json({ error: "Error tunneling to Sentry" }); + } +} \ No newline at end of file