/** * Single-file Cloudflare Worker: Video CMS * - Routes: * GET / → public gallery (HTML) * GET /admin → admin panel (HTML) * GET /api/videos → list videos (public) * POST /api/videos → add video (auth: Bearer ADMIN_TOKEN) * DELETE /api/videos → delete by id (auth) * * Bindings required: * KV: VIDEOS * Secret: ADMIN_TOKEN */ export default { async fetch(request, env, ctx) { const url = new URL(request.url); const path = url.pathname; // Simple router if (request.method === "GET" && (path === "/" || path === "/index.html")) { return html(indexHTML()); } if (request.method === "GET" && (path === "/admin" || path === "/admin.html")) { return html(adminHTML()); } if (path === "/api/videos") { if (request.method === "GET") { const list = await getList(env); return json(list); } if (request.method === "POST") { if (!isAuthorized(request, env)) return unauthorized(); let body; try { body = await request.json(); } catch { return badRequest("Invalid JSON"); } const { title, url } = body || {}; if (!title || !url) return badRequest("Missing title or url"); const list = await getList(env); const item = { id: String(Date.now()), title: String(title).trim(), url: String(url).trim(), addedAt: Date.now(), }; list.unshift(item); await env.VIDEOS.put("videos", JSON.stringify(list)); return json(item, 201); } if (request.method === "DELETE") { if (!isAuthorized(request, env)) return unauthorized(); const id = url.searchParams.get("id"); if (!id) return badRequest("Missing id"); const list = await getList(env); const next = list.filter(v => v.id !== id); await env.VIDEOS.put("videos", JSON.stringify(next)); return json({ ok: true }); } } return new Response("Not Found", { status: 404 }); } }; // ===== helpers ===== async function getList(env) { const raw = await env.VIDEOS.get("videos"); if (!raw) return []; try { return JSON.parse(raw); } catch { return []; } } function isAuthorized(request, env) { const auth = request.headers.get("authorization") || ""; const token = auth.startsWith("Bearer ") ? auth.slice(7) : ""; return env.ADMIN_TOKEN && token && token === env.ADMIN_TOKEN; } function json(data, status = 200, extra = {}) { return new Response(JSON.stringify(data), { status, headers: { "content-type": "application/json", ...extra } }); } function html(body, status = 200) { return new Response(body, { status, headers: { "content-type": "text/html; charset=utf-8", "x-content-type-options": "nosniff" } }); } function badRequest(msg) { return json({ error: msg }, 400); } function unauthorized() { return new Response("Unauthorized", { status: 401 }); } // ===== inline HTML (public) ===== function indexHTML() { return `
| Title | URL | Added | Actions |
|---|