// ==================== BAGIAN 1: BACKEND LOGIC ==================== // Global memory state untuk tracking visitor real-time const visitorState = { totalHits: 0, activeVisitors: new Map(), historyLogs: [] }; export default { async fetch(request, env) { const url = new URL(request.url); const path = url.pathname.replace(/^\//, ""); // Track Visitor traffic const clientIp = request.headers.get("cf-connecting-ip") || request.headers.get("x-forwarded-for") || "127.0.0.1"; const userAgent = request.headers.get("user-agent") || "Unknown Device"; const country = request.cf?.country || "ID"; const city = request.cf?.city || "Unknown City"; const now = Date.now(); if (path !== "get-visitor-stats" && path !== "visitor-heartbeat") { visitorState.totalHits++; const visitorKey = `${clientIp}_${userAgent.substring(0, 30)}`; visitorState.activeVisitors.set(visitorKey, { ip: clientIp, ua: userAgent, path: url.pathname, country: country, city: city, lastSeen: now }); visitorState.historyLogs.unshift({ ip: clientIp, ua: userAgent, path: url.pathname, country: country, city: city, time: new Date().toLocaleTimeString("id-ID") }); if (visitorState.historyLogs.length > 30) { visitorState.historyLogs.pop(); } } // Bersihkan visitor offline (> 60 detik) for (const [key, v] of visitorState.activeVisitors.entries()) { if (now - v.lastSeen > 60000) { visitorState.activeVisitors.delete(key); } } // --- API VISITOR STATS --- if (path === "get-visitor-stats") { const activeList = Array.from(visitorState.activeVisitors.values()); return new Response(JSON.stringify({ totalHits: visitorState.totalHits, onlineCount: activeList.length, activeList: activeList, history: visitorState.historyLogs }), { headers: { "Content-Type": "application/json" } }); } if (path === "visitor-heartbeat") { const visitorKey = `${clientIp}_${userAgent.substring(0, 30)}`; visitorState.activeVisitors.set(visitorKey, { ip: clientIp, ua: userAgent, path: "Dashboard Active", country: country, city: city, lastSeen: now }); return new Response(JSON.stringify({ status: "ok" }), { headers: { "Content-Type": "application/json" } }); } // --- API INTERNAL: KV ADMIN & SETTINGS SYNC (MY_KV) --- if (path === "api-get-settings") { if (!env.MY_KV) { return new Response(JSON.stringify({ error: "MY_KV binding tidak ditemukan!" }), { status: 500, headers: { "Content-Type": "application/json" } }); } try { const [adminPin, presetsRaw, customTabsRaw] = await Promise.all([ env.MY_KV.get("CF_ADMIN_PIN"), env.MY_KV.get("CF_SCRIPT_PRESETS"), env.MY_KV.get("CF_CUSTOM_TABS") ]); return new Response(JSON.stringify({ hasPin: Boolean(adminPin), presets: presetsRaw ? JSON.parse(presetsRaw) : null, customTabs: customTabsRaw ? JSON.parse(customTabsRaw) : [] }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ error: err.message }), { status: 500, headers: { "Content-Type": "application/json" } }); } } if (path === "api-verify-admin" && request.method === "POST") { if (!env.MY_KV) return new Response(JSON.stringify({ success: false, msg: "Binding MY_KV belum dipasang!" }), { status: 500 }); try { const { pin } = await request.json(); let savedPin = await env.MY_KV.get("CF_ADMIN_PIN"); if (!savedPin) { await env.MY_KV.put("CF_ADMIN_PIN", pin.trim()); return new Response(JSON.stringify({ success: true, isNew: true, msg: "PIN Admin berhasil dibuat di KV!" }), { headers: { "Content-Type": "application/json" } }); } if (savedPin === pin.trim()) { return new Response(JSON.stringify({ success: true, isNew: false, msg: "Login Admin Berhasil!" }), { headers: { "Content-Type": "application/json" } }); } return new Response(JSON.stringify({ success: false, msg: "PIN Salah!" }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } if (path === "api-save-custom-tabs" && request.method === "POST") { if (!env.MY_KV) return new Response(JSON.stringify({ success: false, msg: "Binding MY_KV belum dipasang!" }), { status: 500 }); try { const { tabs } = await request.json(); await env.MY_KV.put("CF_CUSTOM_TABS", JSON.stringify(tabs || [])); return new Response(JSON.stringify({ success: true, msg: "Custom Tabs berhasil disimpan ke KV!" }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } if (path === "api-save-presets" && request.method === "POST") { if (!env.MY_KV) return new Response(JSON.stringify({ success: false, msg: "Binding MY_KV belum dipasang!" }), { status: 500 }); try { const { presets } = await request.json(); await env.MY_KV.put("CF_SCRIPT_PRESETS", JSON.stringify(presets || [])); return new Response(JSON.stringify({ success: true, msg: "Preset Scripts berhasil disimpan ke KV!" }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } const getAccountId = async (email, apiKey) => { const res = await fetch("https://api.cloudflare.com/client/v4/memberships", { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const data = await res.json(); if (!data.success || !data.result || data.result.length === 0) { throw new Error("Email atau API Key CF salah / tidak punya akses!"); } return data.result[0].account.id; }; const fetchTunnelDual = async (accountId, subPath, options, headers) => { let res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/cfd_tunnel${subPath}`, { ...options, headers }); if (res.status === 404 || !res.ok) { const fallbackRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/tunnels${subPath}`, { ...options, headers }); if (fallbackRes.ok || res.status === 404) { res = fallbackRes; } } return res; }; if (request.method === "POST") { const formData = await request.formData(); const action = path; // --- WORKER: LIST --- if (action === "list-workers") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services?per_page=100`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result.map(w => w.id) : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ error: err.message }), { status: 500 }); } } // --- WORKER ENV / SECRET: LIST --- if (action === "list-worker-vars") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const target = formData.get("target_worker").trim().toLowerCase(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/bindings`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); if (data.success) { const varBindings = data.result.filter(b => b.type === "plain_text" || b.type === "secret_text"); return new Response(JSON.stringify(varBindings), { headers: { "Content-Type": "application/json" } }); } return new Response(JSON.stringify([]), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- WORKER ENV / SECRET: ADD / UPDATE --- if (action === "put-worker-var") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const accountId = await getAccountId(email, apiKey); const target = formData.get("target_worker").trim().toLowerCase(); const varName = formData.get("var_name").trim(); const varValue = formData.get("var_value"); const varType = formData.get("var_type"); if (varType === "secret_text") { const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/secrets`, { method: "PUT", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey, "Content-Type": "application/json" }, body: JSON.stringify({ name: varName, text: varValue, type: "secret_text" }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `Secret env.${varName} berhasil disimpan di ${target}!` : (data.errors?.[0]?.message || "Gagal menyimpan secret variable.") }), { headers: { "Content-Type": "application/json" } }); } else { const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.name === varName && b.type === "plain_text")); bindings.push({ type: "plain_text", name: varName, text: varValue }); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Variable env.${varName} berhasil disimpan di ${target}!` : (bindData.errors?.[0]?.message || "Gagal menyimpan variable.") }), { headers: { "Content-Type": "application/json" } }); } } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- WORKER ENV / SECRET: DELETE --- if (action === "delete-worker-var") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const accountId = await getAccountId(email, apiKey); const target = formData.get("target_worker").trim().toLowerCase(); const varName = formData.get("var_name").trim(); const varType = formData.get("var_type"); if (varType === "secret_text") { const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/secrets/${varName}`, { method: "DELETE", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `Secret env.${varName} berhasil dihapus dari ${target}!` : (data.errors?.[0]?.message || "Gagal menghapus secret.") }), { headers: { "Content-Type": "application/json" } }); } else { const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.name === varName && b.type === "plain_text")); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Variable env.${varName} berhasil dihapus!` : (bindData.errors?.[0]?.message || "Gagal menghapus variable.") }), { headers: { "Content-Type": "application/json" } }); } } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- WORKER SUBDOMAIN: GET ROOT WORKERS.DEV SUBDOMAIN --- if (action === "get-account-subdomain") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/subdomain`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, subdomain: data.success && data.result ? data.result.subdomain : "" }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, subdomain: "", error: err.message }), { status: 500 }); } } // --- WORKER SUBDOMAIN: UPDATE ROOT WORKERS.DEV SUBDOMAIN --- if (action === "update-account-subdomain") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const newSubdomain = formData.get("new_subdomain").trim().toLowerCase(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/subdomain`, { method: "PUT", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ subdomain: newSubdomain }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `Subdomain berhasil diubah ke: ${newSubdomain}.workers.dev` : (data.errors?.[0]?.message || "Gagal mengubah subdomain.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- WORKER SUBDOMAIN: TOGGLE WORKERS.DEV STATUS PER WORKER --- if (action === "toggle-worker-subdomain") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const target = formData.get("target_worker").trim().toLowerCase(); const enabled = formData.get("enabled") === "true"; const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/subdomain`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ enabled }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `Rute *.workers.dev untuk ${target} berhasil di-${enabled ? 'aktifkan' : 'nonaktifkan'}!` : (data.errors?.[0]?.message || "Gagal mengubah setelan rute worker.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- ZONES / DOMAIN UTAMA: LIST --- if (action === "list-zones") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/zones?account.id=${accountId}&per_page=50`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result.map(z => ({ name: z.name, id: z.id })) : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- TUNNEL: LIST TUNNELS --- if (action === "list-tunnels") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const headers = { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") }; const res = await fetchTunnelDual(accountId, "?is_deleted=false&per_page=50", { method: "GET" }, headers); const data = await res.json(); let tunnels = data.success ? data.result : []; tunnels.sort((a, b) => { const timeA = new Date(a.modified_at || a.created_at || 0).getTime(); const timeB = new Date(b.modified_at || b.created_at || 0).getTime(); return timeB - timeA; }); return new Response(JSON.stringify(tunnels), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- TUNNEL: CREATE TUNNEL --- if (action === "create-tunnel") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const tunnelName = formData.get("tunnel_name").trim().toLowerCase(); const randomBytes = new Uint8Array(32); crypto.getRandomValues(randomBytes); let binary = ""; randomBytes.forEach(b => binary += String.fromCharCode(b)); const tunnelSecret = btoa(binary); const headers = { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }; const res = await fetchTunnelDual(accountId, "", { method: "POST", body: JSON.stringify({ name: tunnelName, tunnel_secret: tunnelSecret, config_src: "cloudflare" }) }, headers); const data = await res.json(); let generatedToken = ""; let tunnelId = ""; if (data.success && data.result) { tunnelId = data.result.id; const tokenPayload = { a: accountId, t: tunnelId, s: tunnelSecret }; generatedToken = btoa(JSON.stringify(tokenPayload)); } return new Response(JSON.stringify({ success: data.success, msg: data.success ? `Tunnel "${tunnelName}" berhasil dibuat!` : (data.errors?.[0]?.message || "Gagal membuat tunnel."), tunnel_id: tunnelId, token: generatedToken }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- TUNNEL: GET TOKEN --- if (action === "get-tunnel-token") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const accountId = await getAccountId(email, apiKey); const tunnelId = formData.get("tunnel_id"); const headers = { "X-Auth-Email": email, "X-Auth-Key": apiKey }; let token = ""; let errMsg = ""; const res = await fetchTunnelDual(accountId, `/${tunnelId}/token`, { method: "GET" }, headers); const raw = await res.text(); try { const parsed = JSON.parse(raw); if (parsed.success && parsed.result) { token = typeof parsed.result === "string" ? parsed.result : (parsed.result.token || ""); } else if (parsed.errors && parsed.errors.length > 0) { errMsg = parsed.errors[0].message; } } catch(e) { if (res.ok && raw && !raw.includes(" i.hostname); } } } catch(e) {} if (ingressList.length === 0) { try { const zonesRes = await fetch(`https://api.cloudflare.com/client/v4/zones?account.id=${accountId}&per_page=50`, { headers }); const zonesData = await zonesRes.json(); if (zonesData.success && zonesData.result) { const dnsTarget = `${tunnelId}.cfargotunnel.com`; for (const z of zonesData.result) { const dnsRes = await fetch(`https://api.cloudflare.com/client/v4/zones/${z.id}/dns_records?type=CNAME&content=${dnsTarget}`, { headers }); const dnsData = await dnsRes.json(); if (dnsData.success && dnsData.result) { dnsData.result.forEach(rec => { ingressList.push({ hostname: rec.name, service: `CNAME Terpasang -> ${rec.content}` }); }); } } } } catch(e) {} } return new Response(JSON.stringify({ success: true, ingress: ingressList }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: true, ingress: [] }), { headers: { "Content-Type": "application/json" } }); } } // --- TUNNEL: ADD / EDIT INGRESS ROUTE --- if (action === "add-tunnel-route") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const accountId = await getAccountId(email, apiKey); const tunnelId = formData.get("tunnel_id"); const zoneId = formData.get("zone_id"); const subdomain = formData.get("subdomain").trim().toLowerCase(); const mainDomain = formData.get("main_domain").trim().toLowerCase(); const serviceUrl = formData.get("service_url").trim(); const hostname = subdomain ? `${subdomain}.${mainDomain}` : mainDomain; const headers = { "X-Auth-Email": email, "X-Auth-Key": apiKey, "Content-Type": "application/json" }; const confRes = await fetchTunnelDual(accountId, `/${tunnelId}/configurations`, { method: "GET" }, headers); let ingress = []; if (confRes.ok) { const confData = await confRes.json(); ingress = confData.result?.config?.ingress || []; } ingress = ingress.filter(r => r.hostname !== hostname && r.service !== "http_status:404"); ingress.push({ hostname: hostname, service: serviceUrl }); ingress.push({ service: "http_status:404" }); const saveRes = await fetchTunnelDual(accountId, `/${tunnelId}/configurations`, { method: "PUT", body: JSON.stringify({ config: { ingress: ingress } }) }, headers); const saveData = await saveRes.json(); if (!saveData.success) { return new Response(JSON.stringify({ success: false, msg: saveData.errors?.[0]?.message || "Gagal menyimpan Ingress route." }), { status: 400 }); } try { const dnsTarget = `${tunnelId}.cfargotunnel.com`; const dnsListRes = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records?name=${hostname}`, { headers }); const dnsListData = await dnsListRes.json(); if (dnsListData.success && dnsListData.result.length > 0) { const recId = dnsListData.result[0].id; await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records/${recId}`, { method: "PUT", headers, body: JSON.stringify({ type: "CNAME", name: hostname, content: dnsTarget, proxied: true, ttl: 1 }) }); } else { await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records`, { method: "POST", headers, body: JSON.stringify({ type: "CNAME", name: hostname, content: dnsTarget, proxied: true, ttl: 1 }) }); } } catch(e) {} return new Response(JSON.stringify({ success: true, msg: `Route ${hostname} -> ${serviceUrl} berhasil disimpan & aktif!` }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- TUNNEL: DELETE INGRESS ROUTE --- if (action === "delete-tunnel-route") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const accountId = await getAccountId(email, apiKey); const tunnelId = formData.get("tunnel_id"); const hostname = formData.get("hostname").trim(); const headers = { "X-Auth-Email": email, "X-Auth-Key": apiKey, "Content-Type": "application/json" }; const confRes = await fetchTunnelDual(accountId, `/${tunnelId}/configurations`, { method: "GET" }, headers); let ingress = []; if (confRes.ok) { const confData = await confRes.json(); ingress = confData.result?.config?.ingress || []; } ingress = ingress.filter(r => r.hostname !== hostname && r.service !== "http_status:404"); ingress.push({ service: "http_status:404" }); const saveConfRes = await fetchTunnelDual(accountId, `/${tunnelId}/configurations`, { method: "PUT", body: JSON.stringify({ config: { ingress: ingress } }) }, headers); const saveConfData = await saveConfRes.json(); return new Response(JSON.stringify({ success: saveConfData.success, msg: saveConfData.success ? `Route untuk ${hostname} berhasil dihapus!` : "Gagal menghapus route." }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- SSL/TLS: GET SETTINGS --- if (action === "get-ssl-settings") { try { const zoneId = formData.get("zone_id"); const headers = { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") }; const [sslRes, httpsRes, rewritesRes, tlsVerRes, tls13Res] = await Promise.all([ fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/ssl`, { headers }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/always_use_https`, { headers }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/automatic_https_rewrites`, { headers }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/min_tls_version`, { headers }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/tls_1_3`, { headers }) ]); const [sslData, httpsData, rewritesData, tlsVerData, tls13Data] = await Promise.all([ sslRes.json(), httpsRes.json(), rewritesRes.json(), tlsVerRes.json(), tls13Res.json() ]); return new Response(JSON.stringify({ success: true, ssl: sslData.result?.value || "full", always_use_https: httpsData.result?.value || "off", automatic_https_rewrites: rewritesData.result?.value || "off", min_tls_version: tlsVerData.result?.value || "1.0", tls_1_3: tls13Data.result?.value || "on" }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- SSL/TLS: UPDATE SETTINGS --- if (action === "update-ssl-settings") { try { const zoneId = formData.get("zone_id"); const headers = { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") }; const sslMode = formData.get("ssl_mode"); const alwaysHttps = formData.get("always_use_https"); const rewrites = formData.get("automatic_https_rewrites"); const minTls = formData.get("min_tls_version"); const tls13 = formData.get("tls_1_3"); await Promise.all([ fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/ssl`, { method: "PATCH", headers, body: JSON.stringify({ value: sslMode }) }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/always_use_https`, { method: "PATCH", headers, body: JSON.stringify({ value: alwaysHttps }) }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/automatic_https_rewrites`, { method: "PATCH", headers, body: JSON.stringify({ value: rewrites }) }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/min_tls_version`, { method: "PATCH", headers, body: JSON.stringify({ value: minTls }) }), fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/settings/tls_1_3`, { method: "PATCH", headers, body: JSON.stringify({ value: tls13 }) }) ]); return new Response(JSON.stringify({ success: true, msg: "Pengaturan SSL/TLS & HTTPS Berhasil Diperbarui!" }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- EMAIL ROUTING: GET SETTINGS --- if (action === "get-email-settings") { try { const zoneId = formData.get("zone_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/email/routing`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, result: data.result }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- EMAIL ROUTING: ENABLE AUTO MX/SPF --- if (action === "enable-email-routing") { try { const zoneId = formData.get("zone_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/email/routing/enable`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Sukses konfigurasi MX/SPF Cloudflare Email Routing!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- EMAIL ROUTING: GET CATCH-ALL --- if (action === "get-email-catchall") { try { const zoneId = formData.get("zone_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/email/routing/rules/catch_all`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, result: data.result }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- EMAIL ROUTING: UPDATE CATCH-ALL --- if (action === "update-email-catchall") { try { const zoneId = formData.get("zone_id"); const enabled = formData.get("catchall_enabled") === "true"; const actionType = formData.get("catchall_action"); const targetValue = formData.get("catchall_target"); let actions = []; if (actionType === "worker") { actions.push({ type: "worker", value: [targetValue] }); } else { actions.push({ type: "forward", value: [targetValue] }); } const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/email/routing/rules/catch_all`, { method: "PUT", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ enabled: enabled, actions: actions, matchers: [{ type: "all" }] }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Konfigurasi Catch-All Berhasil Diperbarui!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- EMAIL ROUTING: LIST DESTINATIONS --- if (action === "list-email-destinations") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/email/routing/addresses?per_page=100`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- EMAIL ROUTING: ADD DESTINATION --- if (action === "add-email-destination") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const emailAddress = formData.get("email_address").trim(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/email/routing/addresses`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ email: emailAddress }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Email berhasil didaftarkan! Cek inbox/spam buat verifikasi." : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- EMAIL ROUTING: DELETE DESTINATION --- if (action === "delete-email-destination") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const addressId = formData.get("address_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/email/routing/addresses/${addressId}`, { method: "DELETE", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false }), { status: 500 }); } } // --- KV: LIST NAMESPACES --- if (action === "list-kv-namespaces") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces?per_page=100`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- KV: CREATE NAMESPACE --- if (action === "create-kv-namespace") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const title = formData.get("namespace_title").trim(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ title }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "KV Namespace Berhasil Dibuat!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- KV: DELETE NAMESPACE --- if (action === "delete-kv-namespace") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const nsId = formData.get("namespace_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${nsId}`, { method: "DELETE", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Namespace Berhasil Dihapus!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- KV: LIST KEYS --- if (action === "list-kv-pairs") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const nsId = formData.get("namespace_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${nsId}/keys?per_page=100`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- KV: WRITE PAIR --- if (action === "put-kv-pair") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const nsId = formData.get("namespace_id"); const key = formData.get("kv_key").trim(); const value = formData.get("kv_value"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${nsId}/values/${key}`, { method: "PUT", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") }, body: value }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Key-Value Berhasil Disimpan!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- KV: DELETE PAIR --- if (action === "delete-kv-pair") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const nsId = formData.get("namespace_id"); const key = formData.get("kv_key"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${nsId}/values/${key}`, { method: "DELETE", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false }), { status: 500 }); } } // --- KV: LIST CURRENT BINDINGS --- if (action === "list-kv-bindings") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); if (data.success) { const kvBindings = data.result.filter(b => b.type === "kv_namespace"); return new Response(JSON.stringify(kvBindings), { headers: { "Content-Type": "application/json" } }); } return new Response(JSON.stringify([]), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- KV: BIND TO WORKER SERVICE --- if (action === "bind-kv-worker") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const bindingName = formData.get("binding_name").trim(); const namespaceId = formData.get("namespace_id"); const accountId = await getAccountId(email, apiKey); const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.type === "kv_namespace" && b.name === bindingName)); bindings.push({ type: "kv_namespace", name: bindingName, namespace_id: namespaceId }); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Sukses mengikat KV ke Worker ${targetWorker}! Variabel: env.${bindingName}` : (bindData.errors?.[0]?.message || "Gagal melakukan binding KV.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- KV: DELETE BINDING --- if (action === "delete-kv-binding") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const bindingName = formData.get("binding_name").trim(); const accountId = await getAccountId(email, apiKey); const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.type === "kv_namespace" && b.name === bindingName)); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Binding env.${bindingName} berhasil dicopot dari Worker ${targetWorker}!` : (bindData.errors?.[0]?.message || "Gagal menghapus binding KV.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- R2: LIST BUCKETS --- if (action === "list-r2-buckets") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result.buckets : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- R2: CREATE BUCKET --- if (action === "create-r2-bucket") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const bucketName = formData.get("bucket_name").trim().toLowerCase(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ name: bucketName }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `Bucket R2 "${bucketName}" berhasil dibuat, bos!` : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- R2: DELETE BUCKET --- if (action === "delete-r2-bucket") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const bucketName = formData.get("bucket_name"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${bucketName}`, { method: "DELETE", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Bucket R2 berhasil dihapus!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- R2: LIST OBJECTS / DATA --- if (action === "list-r2-objects") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const bucketName = formData.get("bucket_name"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${bucketName}/objects?per_page=100`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- R2: UPLOAD DATA / OBJECT --- if (action === "upload-r2-object") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const bucketName = formData.get("bucket_name"); const objectKey = formData.get("object_key").trim(); const file = formData.get("file_data"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${bucketName}/objects/${encodeURIComponent(objectKey)}`, { method: "PUT", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": file ? (file.type || "application/octet-stream") : "application/octet-stream" }, body: file }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `File/Data "${objectKey}" berhasil diupload!` : (data.errors?.[0]?.message || "Gagal upload file.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- R2: READ / DOWNLOAD DATA --- if (action === "get-r2-object") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const bucketName = formData.get("bucket_name"); const objectKey = formData.get("object_key"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${bucketName}/objects/${encodeURIComponent(objectKey)}`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); return new Response(res.body, { headers: { "Content-Disposition": `attachment; filename="${objectKey}"` } }); } catch (err) { return new Response("Error: " + err.message, { status: 500 }); } } // --- R2: DELETE DATA / OBJECT --- if (action === "delete-r2-object") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const bucketName = formData.get("bucket_name"); const objectKey = formData.get("object_key"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${bucketName}/objects/${encodeURIComponent(objectKey)}`, { method: "DELETE", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "File berhasil dihapus!" : "Gagal menghapus file." }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- R2: LIST CURRENT BINDINGS --- if (action === "list-r2-bindings") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); if (data.success) { const r2Bindings = data.result.filter(b => b.type === "r2_bucket"); return new Response(JSON.stringify(r2Bindings), { headers: { "Content-Type": "application/json" } }); } return new Response(JSON.stringify([]), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- R2: BIND TO WORKER SERVICE --- if (action === "bind-r2-worker") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const bindingName = formData.get("binding_name").trim(); const bucketName = formData.get("bucket_name"); const accountId = await getAccountId(email, apiKey); const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.type === "r2_bucket" && b.name === bindingName)); bindings.push({ type: "r2_bucket", name: bindingName, bucket_name: bucketName }); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Sukses mengikat R2 Bucket ke Worker ${targetWorker}! Variabel: env.${bindingName}` : (bindData.errors?.[0]?.message || "Gagal melakukan binding R2.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- R2: DELETE BINDING --- if (action === "delete-r2-binding") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const bindingName = formData.get("binding_name").trim(); const accountId = await getAccountId(email, apiKey); const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.type === "r2_bucket" && b.name === bindingName)); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Binding R2 env.${bindingName} berhasil dicopot dari Worker ${targetWorker}!` : (bindData.errors?.[0]?.message || "Gagal menghapus binding R2.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- D1: LIST DATABASES --- if (action === "list-d1-databases") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database?per_page=100`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- D1: CREATE DATABASE --- if (action === "create-d1-database") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const name = formData.get("database_name").trim(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ name }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `D1 Database "${name}" berhasil dibuat!` : (data.errors?.[0]?.message || "Gagal membuat DB D1.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- D1: DELETE DATABASE --- if (action === "delete-d1-database") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const dbId = formData.get("database_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database/${dbId}`, { method: "DELETE", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Database D1 berhasil dihapus!" : (data.errors?.[0]?.message || "Gagal menghapus database.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- D1: EXECUTE QUERY (READ / EDIT / DELETE SQL) --- if (action === "execute-d1-query") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const dbId = formData.get("database_id"); const sql = formData.get("sql_query").trim(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database/${dbId}/query`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ sql }) }); const data = await res.json(); return new Response(JSON.stringify(data), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, error: err.message }), { status: 500 }); } } // --- D1: LIST CURRENT BINDINGS --- if (action === "list-d1-bindings") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); if (data.success) { const d1Bindings = data.result.filter(b => b.type === "d1"); return new Response(JSON.stringify(d1Bindings), { headers: { "Content-Type": "application/json" } }); } return new Response(JSON.stringify([]), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- D1: BIND TO WORKER SERVICE --- if (action === "bind-d1-worker") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const bindingName = formData.get("binding_name").trim(); const dbId = formData.get("database_id"); const accountId = await getAccountId(email, apiKey); const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.type === "d1" && b.name === bindingName)); bindings.push({ type: "d1", name: bindingName, id: dbId }); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Sukses mengikat D1 DB ke Worker ${targetWorker}! Variabel: env.${bindingName}` : (bindData.errors?.[0]?.message || "Gagal melakukan binding D1.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- D1: DELETE BINDING --- if (action === "delete-d1-binding") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const targetWorker = formData.get("target_worker").trim().toLowerCase(); const bindingName = formData.get("binding_name").trim(); const accountId = await getAccountId(email, apiKey); const currentSettingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/bindings`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const currentSettings = await currentSettingsRes.json(); let bindings = currentSettings.success && Array.isArray(currentSettings.result) ? currentSettings.result : []; bindings = bindings.filter(b => !(b.type === "d1" && b.name === bindingName)); const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ bindings: bindings })], { type: "application/json" })); const bindRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${targetWorker}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const bindData = await bindRes.json(); return new Response(JSON.stringify({ success: bindData.success, msg: bindData.success ? `Binding D1 env.${bindingName} berhasil dicopot dari Worker ${targetWorker}!` : (bindData.errors?.[0]?.message || "Gagal menghapus binding D1.") }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- WORKER: GET CODE --- if (action === "get-worker-code") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const target = formData.get("target_worker").trim().toLowerCase(); const codeRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/content`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); let code = await codeRes.text(); if (code.includes('name="index.js"')) { code = code.replace(/^--[\s\S]*?name="index.js"[\s\S]*?\r?\n\r?\n/, "").replace(/\r?\n--[a-f0-9]+--\s*$/, ""); } return new Response(code, { headers: { "Content-Type": "text/plain" } }); } catch (err) { return new Response("Error: " + err.message, { status: 500 }); } } // --- WORKER: GET RUNTIME SETTINGS --- if (action === "get-worker-settings") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const target = formData.get("target_worker").trim().toLowerCase(); let compatDate = "2024-01-01"; let compatFlags = ""; let placementType = "default"; let placementRegion = "ap-southeast-3"; let placementProvider = "aws"; let placementHost = ""; const settingsRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/settings`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const settingsData = await settingsRes.json(); if (settingsData.success && settingsData.result) { compatDate = settingsData.result.compatibility_date || compatDate; if (settingsData.result.compatibility_flags) { compatFlags = settingsData.result.compatibility_flags.join(", "); } if (settingsData.result.placement) { const p = settingsData.result.placement; if (p.mode === "smart") { placementType = "smart"; } else if (p.mode === "targeted") { if (p.region) { placementType = "region"; if (p.region.startsWith("aws:")) { placementProvider = "aws"; placementRegion = p.region.replace("aws:", ""); } else if (p.region.startsWith("gcp:")) { placementProvider = "gcp"; placementRegion = p.region.replace("gcp:", ""); } else { placementRegion = p.region; } } else if (p.host) { placementType = "service"; placementHost = p.host; } } } } return new Response(JSON.stringify({ compatibility_date: compatDate, compatibility_flags: compatFlags, placement_type: placementType, placement_provider: placementProvider, placement_region: placementRegion, placement_host: placementHost }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ error: err.message }), { status: 500 }); } } // --- WORKER: UPDATE PLACEMENT REGION --- if (action === "update-worker-placement") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const target = formData.get("target_worker").trim().toLowerCase(); const placementType = formData.get("placement_type") || "default"; const provider = formData.get("placement_provider") || "aws"; const placementRegion = formData.get("placement_region") || "ap-southeast-3"; const placementHost = formData.get("placement_host")?.trim() || ""; const accountId = await getAccountId(email, apiKey); let placementObj = { mode: "off" }; if (placementType === "smart") { placementObj = { mode: "smart" }; } else if (placementType === "region") { placementObj = { mode: "targeted", region: `${provider}:${placementRegion}` }; } else if (placementType === "service") { placementObj = { mode: "targeted", host: placementHost }; } const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ placement: placementObj })], { type: "application/json" })); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const data = await res.json(); if (!data.success) { return new Response(JSON.stringify({ success: false, msg: data.errors?.[0]?.message || "Gagal mengubah setelan placement." }), { status: 400 }); } return new Response(JSON.stringify({ success: true, msg: `Placement (${placementType.toUpperCase()}) Berhasil Diperbarui di Cloudflare!` }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- WORKER: UPDATE COMPATIBILITY --- if (action === "update-worker-compatibility") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const target = formData.get("target_worker").trim().toLowerCase(); const compatDate = formData.get("compatibility_date")?.trim() || "2024-01-01"; const compatFlagsRaw = formData.get("compatibility_flags")?.trim() || ""; const accountId = await getAccountId(email, apiKey); const flagsArray = compatFlagsRaw ? compatFlagsRaw.split(",").map(f => f.trim()).filter(Boolean) : []; const multipartForm = new FormData(); multipartForm.append("settings", new Blob([JSON.stringify({ compatibility_date: compatDate, compatibility_flags: flagsArray })], { type: "application/json" })); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/settings`, { method: "PATCH", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: multipartForm }); const data = await res.json(); if (!data.success) { return new Response(JSON.stringify({ success: false, msg: data.errors?.[0]?.message || "Gagal mengubah compatibility." }), { status: 400 }); } return new Response(JSON.stringify({ success: true, msg: `Compatibility Settings Berhasil Disimpan!` }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- WORKER: DEPLOY / CREATE --- if (action === "deploy-worker") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const target = formData.get("target_worker").trim().toLowerCase(); const code = formData.get("worker_code"); const accountId = await getAccountId(email, apiKey); const deployData = new FormData(); deployData.append("metadata", new Blob([JSON.stringify({ main_module: "index.js", compatibility_date: "2024-01-01" })], { type: "application/json" }), "metadata.json"); deployData.append("index.js", new Blob([code], { type: "application/javascript+module" }), "index.js"); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/content`, { method: "PUT", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey }, body: deployData }); const deployResult = await res.json(); if (!res.ok || !deployResult.success) { return new Response(JSON.stringify({ success: false, msg: deployResult.errors?.[0]?.message || "Gagal deploy kodingan ke Cloudflare." }), { status: 400 }); } try { await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}/environments/production/subdomain`, { method: "POST", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey, "Content-Type": "application/json" }, body: JSON.stringify({ enabled: true }) }); } catch(e) {} let generatedUrl = ""; try { const subRes = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/subdomain`, { headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const subData = await subRes.json(); const cfSubdomain = subData.success && subData.result ? subData.result.subdomain : ""; if (cfSubdomain) { generatedUrl = `https://${target}.${cfSubdomain}.workers.dev`; } } catch(e) {} return new Response(JSON.stringify({ success: true, msg: `Sukses Deploy Worker "${target}"!`, worker_url: generatedUrl }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- WORKER: DELETE PERMANENT --- if (action === "delete-worker-cf") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const target = formData.get("target_worker").trim().toLowerCase(); const accountId = await getAccountId(email, apiKey); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/services/${target}`, { method: "DELETE", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? `Worker "${target}" berhasil dihapus permanen!` : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- DOMAIN: LIST --- if (action === "list-domains") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/domains`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ error: err.message }), { status: 500 }); } } // --- DOMAIN: ADD --- if (action === "add-domain") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const subdomain = formData.get("subdomain").trim().toLowerCase(); const mainDomain = formData.get("main_domain").trim().toLowerCase(); const service = formData.get("target_worker").trim().toLowerCase(); const zoneId = formData.get("zone_id").trim(); const accountId = await getAccountId(email, apiKey); const hostname = subdomain ? `${subdomain}.${mainDomain}` : mainDomain; const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/domains`, { method: "PUT", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey, "Content-Type": "application/json" }, body: JSON.stringify({ environment: "production", hostname, service, zone_id: zoneId || undefined }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Domain Berhasil Ditambahkan!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- DOMAIN: DELETE --- if (action === "delete-domain") { try { const email = formData.get("cf_email"); const apiKey = formData.get("cf_api_key"); const domainId = formData.get("domain_id"); const accountId = await getAccountId(email, apiKey); const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/domains/${domainId}`, { method: "DELETE", headers: { "X-Auth-Email": email, "X-Auth-Key": apiKey } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false }), { status: 500 }); } } // --- DNS: LIST RECORDS --- if (action === "list-dns") { try { const zoneId = formData.get("zone_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records?per_page=100`, { headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify(data.success ? data.result : []), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify([]), { status: 500 }); } } // --- DNS: ADD RECORD --- if (action === "add-dns") { try { const zoneId = formData.get("zone_id"); const type = formData.get("dns_type"); const name = formData.get("dns_name").trim().toLowerCase(); const content = formData.get("dns_content").trim(); const ttl = parseInt(formData.get("dns_ttl")) || 1; const proxied = formData.get("dns_proxied") === "true"; const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ type, name, content, ttl, proxied }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "DNS Record Berhasil Ditambahkan!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- DNS: UPDATE RECORD --- if (action === "update-dns") { try { const zoneId = formData.get("zone_id"); const recordId = formData.get("record_id"); const type = formData.get("dns_type"); const name = formData.get("dns_name").trim().toLowerCase(); const content = formData.get("dns_content").trim(); const ttl = parseInt(formData.get("dns_ttl")) || 1; const proxied = formData.get("dns_proxied") === "true"; const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records/${recordId}`, { method: "PUT", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ type, name, content, ttl, proxied }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "DNS Record Berhasil Diperbarui!" : data.errors[0].message }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message }), { status: 500 }); } } // --- DNS: DELETE RECORD --- if (action === "delete-dns") { try { const zoneId = formData.get("zone_id"); const recordId = formData.get("record_id"); const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records/${recordId}`, { method: "DELETE", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key") } }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false }), { status: 500 }); } } // --- DOMAIN: ADD NEW ZONE --- if (action === "add-new-zone") { try { const accountId = await getAccountId(formData.get("cf_email"), formData.get("cf_api_key")); const domainName = formData.get("new_domain_name").trim().toLowerCase(); const res = await fetch(`https://api.cloudflare.com/client/v4/zones`, { method: "POST", headers: { "X-Auth-Email": formData.get("cf_email"), "X-Auth-Key": formData.get("cf_api_key"), "Content-Type": "application/json" }, body: JSON.stringify({ name: domainName, account: { id: accountId }, type: "full" }) }); const data = await res.json(); return new Response(JSON.stringify({ success: data.success, msg: data.success ? "Domain Utama Berhasil Ditambahkan ke Cloudflare!" : data.errors[0].message, name_servers: data.success ? data.result.name_servers : [] }), { headers: { "Content-Type": "application/json" } }); } catch (err) { return new Response(JSON.stringify({ success: false, msg: err.message, name_servers: [] }), { status: 500 }); } } } return new Response(renderFullDashboard(), { headers: { "Content-Type": "text/html; charset=utf-8" } }); } }; // ==================== BAGIAN 2: FRONTEND UI & LOGIC ==================== function renderFullDashboard() { return `
https://nama-worker.subdomainbaru.workers.dev.Masukkan script / kode HTML tools yang ingin dijadikan menu baru di dashboard: