export default { async fetch(request, env) { const url = new URL(request.url); const path = url.pathname.replace(/^\//, ""); // HELPER: Ambil Account ID Cloudflare 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; }; // ================================================================= // BACKEND API – hanya untuk Email Routing // ================================================================= if (request.method === "POST") { const formData = await request.formData(); const action = path; // --- WORKER: LIST (untuk dropdown catch-all) --- 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 }); } } // --- 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 }); } } // --- 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 }); } } // default return new Response("Not found", { status: 404 }); } // ================================================================= // TAMPILAN DASHBOARD EMAIL ROUTING // ================================================================= return new Response(renderDashboard(), { headers: { "Content-Type": "text/html; charset=utf-8" } }); } }; // ==================== FRONTEND UI (Email Routing Only) ==================== function renderDashboard() { return `
Dibuat untuk memudahkan manajemen Email Routing Cloudflare.