From 452c81b151da54d686d93a659cbb48de9d7a1a45 Mon Sep 17 00:00:00 2001 From: mrrfv Date: Fri, 8 Sep 2023 20:10:06 +0200 Subject: [PATCH] Migrate to node-fetch and import syntax #17 --- cf_gateway_rule_create.js | 76 +++++++++++--------- cf_gateway_rule_delete.js | 44 +++++++----- cf_list_create.js | 36 +++++----- cf_list_delete.js | 46 ++++++------ package-lock.json | 144 ++++++++++++++++++-------------------- package.json | 5 +- 6 files changed, 187 insertions(+), 164 deletions(-) diff --git a/cf_gateway_rule_create.js b/cf_gateway_rule_create.js index f33bae9..26e239c 100644 --- a/cf_gateway_rule_create.js +++ b/cf_gateway_rule_create.js @@ -1,5 +1,5 @@ -require("dotenv").config(); -const axios = require('axios'); +import 'dotenv/config'; +import fetch from 'node-fetch'; const API_TOKEN = process.env.CLOUDFLARE_API_KEY; const ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; @@ -7,19 +7,24 @@ const ACCOUNT_EMAIL = process.env.CLOUDFLARE_ACCOUNT_EMAIL; // Function to read Cloudflare Zero Trust lists async function getZeroTrustLists() { - const response = await axios.get( - `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists`, - { - headers: { - 'Authorization': `Bearer ${API_TOKEN}`, - 'Content-Type': 'application/json', - 'X-Auth-Email': ACCOUNT_EMAIL, - 'X-Auth-Key': API_TOKEN, - }, - } - ); + const url = `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists`; - return response.data.result; + const response = await fetch(url, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${API_TOKEN}`, + 'Content-Type': 'application/json', + 'X-Auth-Email': ACCOUNT_EMAIL, + 'X-Auth-Key': API_TOKEN, + }, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data.result; } ;(async() => { @@ -39,25 +44,32 @@ async function getZeroTrustLists() { wirefilter_expression = wirefilter_expression.trim().replace('\n', ''); if (!process.env.CI) console.log(`Firewall expression contains ${wirefilter_expression.length} characters, and checks against ${filtered_lists.length} filter lists.`) - const resp = await axios.request({ - method: 'POST', - url: `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/rules`, - headers: { - 'Authorization': `Bearer ${API_TOKEN}`, - 'Content-Type': 'application/json', - 'X-Auth-Email': ACCOUNT_EMAIL, - 'X-Auth-Key': API_TOKEN, - }, - data: { - "name": "CGPS Filter Lists", - "description": "Filter lists created by Cloudflare Gateway Pi-hole Scripts. Avoid editing this rule. Changing the name of this rule will break the script.", - "enabled": true, - "action": "block", - "filters": ["dns"], - "traffic": wirefilter_expression, - } + const url = `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/rules`; + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${API_TOKEN}`, + 'Content-Type': 'application/json', + 'X-Auth-Email': ACCOUNT_EMAIL, + 'X-Auth-Key': API_TOKEN, + }, + body: JSON.stringify({ + "name": "CGPS Filter Lists", + "description": "Filter lists created by Cloudflare Gateway Pi-hole Scripts. Avoid editing this rule. Changing the name of this rule will break the script.", + "enabled": true, + "action": "block", + "filters": ["dns"], + "traffic": wirefilter_expression, + }), }); - console.log('Success:', resp.data.success); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + console.log('Success:', data.success); })(); async function sleep(ms) { diff --git a/cf_gateway_rule_delete.js b/cf_gateway_rule_delete.js index f41813d..9613d5a 100644 --- a/cf_gateway_rule_delete.js +++ b/cf_gateway_rule_delete.js @@ -1,5 +1,5 @@ -require("dotenv").config(); -const axios = require('axios'); +import 'dotenv/config'; +import fetch from 'node-fetch'; const API_TOKEN = process.env.CLOUDFLARE_API_KEY; const ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; @@ -7,19 +7,24 @@ const ACCOUNT_EMAIL = process.env.CLOUDFLARE_ACCOUNT_EMAIL; // Function to read Cloudflare Zero Trust rules async function getZeroTrustRules() { - const response = await axios.get( - `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/rules`, - { - headers: { - 'Authorization': `Bearer ${API_TOKEN}`, - 'Content-Type': 'application/json', - 'X-Auth-Email': ACCOUNT_EMAIL, - 'X-Auth-Key': API_TOKEN, - }, - } - ); + const url = `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/rules`; - return response.data.result; + const response = await fetch(url, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${API_TOKEN}`, + 'Content-Type': 'application/json', + 'X-Auth-Email': ACCOUNT_EMAIL, + 'X-Auth-Key': API_TOKEN, + }, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data.result; } ;(async() => { @@ -30,9 +35,10 @@ async function getZeroTrustRules() { console.log(`Deleting rule`, process.env.CI ? "(redacted, running in CI)" : `${filtered_rule.name} with ID ${filtered_rule.id}`); - const resp = await axios.request({ + const url = `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/rules/${filtered_rule.id}`; + + const resp = await fetch(url, { method: 'DELETE', - url: `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/rules/${filtered_rule.id}`, headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json', @@ -40,8 +46,10 @@ async function getZeroTrustRules() { 'X-Auth-Key': API_TOKEN, }, }); - - console.log('Success: ', resp.data.success); + + const data = await resp.json(); + + console.log('Success: ', data.success); await sleep(350); // Cloudflare API rate limit is 1200 requests per 5 minutes, so we sleep for 350ms to be safe })(); diff --git a/cf_list_create.js b/cf_list_create.js index 2464663..8d45c37 100644 --- a/cf_list_create.js +++ b/cf_list_create.js @@ -1,6 +1,6 @@ -require("dotenv").config(); -const fs = require('fs'); -const axios = require('axios'); +import 'dotenv/config'; +import fetch from 'node-fetch'; +import fs from 'fs'; const API_TOKEN = process.env.CLOUDFLARE_API_KEY; const ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; @@ -158,24 +158,26 @@ function chunkArray(array, chunkSize) { // Function to create a Cloudflare Zero Trust list async function createZeroTrustList(name, items, currentItem, totalItems) { - const response = await axios.post( - `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists`, - { + const url = `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists`; + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${API_TOKEN}`, + 'Content-Type': 'application/json', + 'X-Auth-Email': ACCOUNT_EMAIL, + 'X-Auth-Key': API_TOKEN, + }, + body: JSON.stringify({ name, type: 'DOMAIN', // Set list type to DOMAIN items, - }, - { - headers: { - 'Authorization': `Bearer ${API_TOKEN}`, - 'Content-Type': 'application/json', - 'X-Auth-Email': ACCOUNT_EMAIL, - 'X-Auth-Key': API_TOKEN, - }, - } - ); + }), + }); + + const data = await response.json(); + const listId = data.result.id; - const listId = response.data.result.id; console.log(`Created Zero Trust list`, process.env.CI ? "(redacted on CI)" : `"${name}" with ID ${listId} - ${totalItems - currentItem} left`); } diff --git a/cf_list_delete.js b/cf_list_delete.js index 18c93de..cf15f4c 100644 --- a/cf_list_delete.js +++ b/cf_list_delete.js @@ -1,5 +1,5 @@ -require("dotenv").config(); -const axios = require('axios'); +import 'dotenv/config'; +import fetch from 'node-fetch'; const API_TOKEN = process.env.CLOUDFLARE_API_KEY; const ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; @@ -7,19 +7,20 @@ const ACCOUNT_EMAIL = process.env.CLOUDFLARE_ACCOUNT_EMAIL; // Function to read Cloudflare Zero Trust lists async function getZeroTrustLists() { - const response = await axios.get( - `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists`, - { - headers: { - 'Authorization': `Bearer ${API_TOKEN}`, - 'Content-Type': 'application/json', - 'X-Auth-Email': ACCOUNT_EMAIL, - 'X-Auth-Key': API_TOKEN, - }, - } - ); + const url = `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists`; - return response.data.result; + const response = await fetch(url, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${API_TOKEN}`, + 'Content-Type': 'application/json', + 'X-Auth-Email': ACCOUNT_EMAIL, + 'X-Auth-Key': API_TOKEN, + }, + }); + + const data = await response.json(); + return data.result; } ;(async() => { @@ -30,21 +31,26 @@ async function getZeroTrustLists() { if (!process.env.CI) console.log(`Got ${lists.length} lists, ${cgps_lists.length} of which are CGPS lists that will be deleted.`); + let lists_processed = 0; for (const list of cgps_lists) { - console.log(`Deleting list`, process.env.CI ? "(redacted, running in CI)" : `${list.name} with ID ${list.id}`); - const resp = await axios.request({ + console.log(`Deleting list`, process.env.CI ? "(info redacted, running in CI)" : `${list.name} with ID ${list.id}, ${cgps_lists.length - lists_processed - 1} left`); + + const resp = await fetch(`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists/${list.id}`, { method: 'DELETE', - url: `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/gateway/lists/${list.id}`, headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json', 'X-Auth-Email': ACCOUNT_EMAIL, 'X-Auth-Key': API_TOKEN, - }, + }, }); - console.log('Success:', resp.data.success); + + const data = await resp.json(); + console.log('Success:', data.success); + lists_processed++; + await sleep(350); // Cloudflare API rate limit is 1200 requests per 5 minutes, so we sleep for 350ms to be safe - } + } })(); async function sleep(ms) { diff --git a/package-lock.json b/package-lock.json index ebd7ac6..f1bf546 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,42 +5,16 @@ "packages": { "": { "dependencies": { - "axios": "^1.4.0", - "dotenv": "^16.0.3" + "dotenv": "^16.0.3", + "node-fetch": "^3.3.2" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "engines": { - "node": ">= 0.8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" + "node": ">= 12" } }, "node_modules/dotenv": { @@ -51,61 +25,81 @@ "node": ">=12" } }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", "funding": [ { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" } ], "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": ">=10.5.0" } }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "engines": { - "node": ">= 0.6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } } } } diff --git a/package.json b/package.json index 5265f2e..123c53c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { + "type": "module", "dependencies": { - "axios": "^1.4.0", - "dotenv": "^16.0.3" + "dotenv": "^16.0.3", + "node-fetch": "^3.3.2" } }