use native fetch and refactored list creation

This commit is contained in:
Viet Huynh
2023-09-09 19:53:47 +07:00
parent f7f9001ec5
commit 43bd87f2dd
5 changed files with 126 additions and 81 deletions
+4 -77
View File
@@ -1,11 +1,6 @@
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;
const ACCOUNT_EMAIL = process.env.CLOUDFLARE_ACCOUNT_EMAIL;
const LIST_ITEM_LIMIT = Number.isSafeInteger(Number(process.env.CLOUDFLARE_LIST_ITEM_LIMIT)) ? Number(process.env.CLOUDFLARE_LIST_ITEM_LIMIT) : 300000;
import { DRY_RUN, LIST_ITEM_LIMIT } from './lib/constants.js';
import { createZeroTrustLists } from './lib/helpers.js';
if (!process.env.CI) console.log(`List item limit set to ${LIST_ITEM_LIMIT}`);
@@ -113,79 +108,11 @@ fs.readFile('input.csv', 'utf8', async (err, data) => {
// If we are dry-running, stop here because we don't want to create lists
// TODO: we should probably continue, just without making any real requests to Cloudflare
if (process.env.DRY_RUN) return console.log('Dry run complete - no lists were created. If this was not intended, please remove the DRY_RUN environment variable and try again.');
if (DRY_RUN) return console.log('Dry run complete - no lists were created. If this was not intended, please remove the DRY_RUN environment variable and try again.');
// Separate domains into chunks of 1000 (Cloudflare list cap)
const chunks = chunkArray(domains, 1000);
// Create Cloudflare Zero Trust lists
for (const [index, chunk] of chunks.entries()) {
const listName = `CGPS List - Chunk ${index}`;
let properList = [];
chunk.forEach(domain => {
properList.push({ "value": domain })
});
try {
await createZeroTrustList(listName, properList, (index+1), listsToCreate);
await sleep(350); // Sleep for 350ms between list additions
} catch (error) {
console.error(`Error creating list `, process.env.CI ? "(redacted on CI)" : `"${listName}": ${error.response.data}`);
}
}
await createZeroTrustLists(domains)
});
function trimArray(arr, size) {
return arr.slice(0, size);
}
// Function to check if a domain is valid
function isValidDomain(domain) {
const regex = /^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,6}$/;
return regex.test(domain);
}
// Function to split an array into chunks
function chunkArray(array, chunkSize) {
const chunks = [];
for (let i = 0; i < array.length; i += chunkSize) {
chunks.push(array.slice(i, i + chunkSize));
}
return chunks;
}
// Function to create a Cloudflare Zero Trust list
async function createZeroTrustList(name, items, currentItem, totalItems) {
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,
}),
});
const data = await response.json();
const listId = data.result.id;
console.log(`Created Zero Trust list`, process.env.CI ? "(redacted on CI)" : `"${name}" with ID ${listId} - ${totalItems - currentItem} left`);
}
function percentage(percent, total) {
return Math.round((percent / 100) * total);
}
// Function to sleep for a specified duration
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}