diff --git a/dashboards/tracker-web/src/app/api/telemetry/ingest/route.ts b/dashboards/tracker-web/src/app/api/telemetry/ingest/route.ts index 6290e708..9d6fde7a 100644 --- a/dashboards/tracker-web/src/app/api/telemetry/ingest/route.ts +++ b/dashboards/tracker-web/src/app/api/telemetry/ingest/route.ts @@ -11,11 +11,23 @@ export async function POST(req: NextRequest) { try { const body = await req.text(); + // The backend telemetry ingest requires a JWT or an X-Install-Token. Browser + // beacons can't set an Authorization header, so derive an install token from + // the payload (installId) with a stable fallback to satisfy the auth gate. + let installToken = 'web-telemetry'; + try { + const parsed = JSON.parse(body); + installToken = parsed.installId || parsed.events?.[0]?.installId || installToken; + } catch { + /* keep fallback */ + } + const res = await fetch(`${PLATFORM_SERVICE_URL}/api/telemetry/events`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Product-Id': PRODUCT_ID, + 'X-Install-Token': installToken, }, body, }); diff --git a/dashboards/tracker-web/src/app/dashboard/fleet/jobs/[id]/page.tsx b/dashboards/tracker-web/src/app/dashboard/fleet/jobs/[id]/page.tsx index 1f0c9268..41370ecc 100644 --- a/dashboards/tracker-web/src/app/dashboard/fleet/jobs/[id]/page.tsx +++ b/dashboards/tracker-web/src/app/dashboard/fleet/jobs/[id]/page.tsx @@ -325,7 +325,14 @@ export default function FleetJobDetailPage() { const t = runTotals(runs); return (