const DEFAULT_PASSWORD = ""; export default { async fetch(request, env, ctx) { const url = new URL(request.url); const password = env.DASHBOARD_PASSWORD || DEFAULT_PASSWORD; if (url.pathname === "/favicon.ico") { return new Response(null, { status: 204 }); } if (request.method === "GET") { if (url.searchParams.get("pass") !== password) { return new Response("Unauthorized. Please provide the correct ?pass= parameter.", { status: 401 }); } if (!env.TELEMETRY_KV) { return new Response("TELEMETRY_KV namespace not bound.", { status: 500 }); } const rawData = []; let cursor = null; let isComplete = false; while (!isComplete) { const kvList = await env.TELEMETRY_KV.list({ prefix: "inst:", cursor }); for (const key of kvList.keys) { if (key.metadata) { rawData.push({ version: key.metadata.v || "unknown", os: key.metadata.o || "unknown", target: key.metadata.t || "unknown", country: key.metadata.c || "unknown", count: 1 // Since each key is a unique instance }); } } isComplete = kvList.list_complete; cursor = kvList.cursor; } // Return the HTML/JS Dashboard return new Response(renderDashboard(rawData), { headers: { "Content-Type": "text/html" } }); } // HANDLE INCOMING TELEMETRY REQUEST if (request.method === "POST") { try { const data = await request.json(); const { InstanceId, os, target, appVersion } = data; if (!InstanceId || !appVersion) { return new Response("Bad Request", { status: 400 }); } // Sanitize string inputs const clean = (val) => String(val || "unknown").replace(/[^a-zA-Z0-9.+-]/g, ""); const sVersion = clean(appVersion); const sOs = clean(os); const sTarget = clean(target); const sId = clean(InstanceId); const sCountry = request.cf && request.cf.country ? String(request.cf.country).replace(/[^a-zA-Z]/g, "") : "unknown"; if (env.TELEMETRY_KV) { await env.TELEMETRY_KV.put(`inst:${sId}`, "", { metadata: { v: sVersion, o: sOs, t: sTarget, c: sCountry, lastSeen: new Date().toISOString() } }); } return new Response(JSON.stringify({ status: "success" }), { status: 200, headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response("Bad Request", { status: 400 }); } } return new Response("Method Not Allowed", { status: 405 }); } }; // HTML & CHART function renderDashboard(data) { return `
| Version | OS | Target | Country | Count |
|---|