Files
wevads-platform/scripts/api_cloudflare-keygen.php
2026-02-26 04:53:11 +01:00

188 lines
8.1 KiB
PHP
Executable File

<?php
/**
* CLOUDFLARE API KEY GENERATOR
* Login to CF accounts, generate Global API keys, then harvest domains
* Flow: login → get API key → list zones → store domains
*/
header('Content-Type: application/json');
require_once("/opt/wevads/config/credentials.php"); $db = pg_connect("host=localhost dbname=adx_system user=admin password=".WEVADS_DB_PASS);
pg_query($db, "SET search_path TO admin");
$action = $_GET['action'] ?? $_POST['action'] ?? 'status';
function cf_login_get_key($email, $password) {
// Step 1: Login to get session
$ch = curl_init('https://dash.cloudflare.com/api/v4/login');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['email' => $email, 'password' => $password]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_HEADER => true,
CURLOPT_TIMEOUT => 30
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['code' => $code, 'needs_2fa' => (strpos($resp, '2fa') !== false), 'raw' => substr($resp, 0, 500)];
}
function cf_api_zones($email, $key, $page=1) {
$ch = curl_init("https://api.cloudflare.com/client/v4/zones?page=$page&per_page=50&status=active");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Auth-Email: $email",
"X-Auth-Key: $key",
"Content-Type: application/json"
],
CURLOPT_TIMEOUT => 30
]);
$resp = curl_exec($ch);
curl_close($ch);
return json_decode($resp, true);
}
switch($action) {
case 'generate_keys':
// Try to get API keys for all accounts without one
$accounts = pg_fetch_all(pg_query($db,
"SELECT id, email, password FROM cloudflare_accounts
WHERE (api_key IS NULL OR api_key='') AND password IS NOT NULL AND password!=''
AND status='active' ORDER BY domains_count DESC"));
if (!$accounts) { echo json_encode(['error' => 'No accounts need keys']); break; }
$results = [];
foreach ($accounts as $acc) {
$login = cf_login_get_key($acc['email'], $acc['password']);
$results[] = [
'id' => $acc['id'],
'email' => $acc['email'],
'login_code' => $login['code'],
'needs_2fa' => $login['needs_2fa'],
'note' => 'Manual key needed - go to dash.cloudflare.com/profile/api-tokens'
];
usleep(500000); // 500ms delay between requests
}
echo json_encode([
'status' => 'info',
'message' => 'CF login API requires captcha/2FA. Use manual approach or API tokens.',
'manual_steps' => [
'1. Login to each CF account at dash.cloudflare.com',
'2. Go to Profile → API Tokens → Global API Key → View',
'3. Copy key and use /api/cloudflare-harvester.php?action=set_key&id=X&key=KEY',
'4. Then run harvest to get all domains'
],
'accounts_needing_keys' => count($accounts),
'results' => array_slice($results, 0, 5)
]);
break;
case 'set_key':
// Manually set API key for an account
$id = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
$key = $_GET['key'] ?? $_POST['key'] ?? '';
if (!$id || !$key) { echo json_encode(['error' => 'Need id and key']); break; }
pg_query($db, "UPDATE cloudflare_accounts SET api_key='".pg_escape_string($db,$key)."', api_status='active', last_api_check=NOW() WHERE id=$id");
// Immediately try to harvest zones
$acc = pg_fetch_assoc(pg_query($db, "SELECT email, api_key FROM cloudflare_accounts WHERE id=$id"));
$zones_resp = cf_api_zones($acc['email'], $acc['api_key']);
$domains = [];
if ($zones_resp['success'] ?? false) {
foreach ($zones_resp['result'] ?? [] as $zone) {
$d = pg_escape_string($db, $zone['name']);
$zid = pg_escape_string($db, $zone['id']);
pg_query($db, "INSERT INTO cloudflare_domains(account_id, domain, zone_id, status, created_at)
VALUES($id, '$d', '$zid', '{$zone['status']}', NOW()) ON CONFLICT DO NOTHING");
$domains[] = $zone['name'];
}
pg_query($db, "UPDATE cloudflare_accounts SET domains_count=".count($domains).", last_api_check=NOW() WHERE id=$id");
}
echo json_encode([
'status' => 'success',
'account_id' => $id,
'api_valid' => ($zones_resp['success'] ?? false),
'domains_found' => count($domains),
'domains' => $domains
]);
break;
case 'bulk_set_keys':
// Set multiple keys at once: POST JSON array [{id:1,key:"xxx"}, ...]
$input = json_decode(file_get_contents('php://input'), true);
$keys = $input['keys'] ?? [];
$results = [];
foreach ($keys as $k) {
$id = (int)$k['id'];
$key = pg_escape_string($db, $k['key']);
pg_query($db, "UPDATE cloudflare_accounts SET api_key='$key', api_status='active', last_api_check=NOW() WHERE id=$id");
$acc = pg_fetch_assoc(pg_query($db, "SELECT email FROM cloudflare_accounts WHERE id=$id"));
$zones = cf_api_zones($acc['email'], $k['key']);
$cnt = 0;
if ($zones['success'] ?? false) {
foreach ($zones['result'] ?? [] as $z) {
$d = pg_escape_string($db, $z['name']);
pg_query($db, "INSERT INTO cloudflare_domains(account_id, domain, zone_id, status, created_at)
VALUES($id, '$d', '".pg_escape_string($db,$z['id'])."', '{$z['status']}', NOW()) ON CONFLICT DO NOTHING");
$cnt++;
}
pg_query($db, "UPDATE cloudflare_accounts SET domains_count=$cnt WHERE id=$id");
}
$results[] = ['id' => $id, 'email' => $acc['email'], 'domains' => $cnt];
}
echo json_encode(['status' => 'success', 'processed' => count($results), 'results' => $results]);
break;
case 'harvest_all':
// Harvest domains from ALL accounts that have API keys
$accounts = pg_fetch_all(pg_query($db,
"SELECT id, email, api_key FROM cloudflare_accounts WHERE api_key IS NOT NULL AND api_key!='' AND status='active'"));
if (!$accounts) { echo json_encode(['error' => 'No accounts with API keys']); break; }
$total = 0;
$results = [];
foreach ($accounts as $acc) {
$page = 1;
$domains = [];
do {
$resp = cf_api_zones($acc['email'], $acc['api_key'], $page);
if (!($resp['success'] ?? false)) break;
foreach ($resp['result'] ?? [] as $z) {
$d = pg_escape_string($db, $z['name']);
pg_query($db, "INSERT INTO cloudflare_domains(account_id, domain, zone_id, status, created_at)
VALUES({$acc['id']}, '$d', '".pg_escape_string($db,$z['id'])."', '{$z['status']}', NOW()) ON CONFLICT DO NOTHING");
pg_query($db, "INSERT INTO domains_pool(domain, provider, status, created_at)
VALUES('$d', 'cloudflare', 'active', NOW()) ON CONFLICT DO NOTHING");
$domains[] = $z['name'];
}
$total_pages = $resp['result_info']['total_pages'] ?? 1;
$page++;
} while ($page <= $total_pages);
pg_query($db, "UPDATE cloudflare_accounts SET domains_count=".count($domains).", last_api_check=NOW() WHERE id={$acc['id']}");
$results[] = ['id' => $acc['id'], 'email' => $acc['email'], 'domains' => count($domains)];
$total += count($domains);
}
echo json_encode(['status' => 'success', 'total_domains' => $total, 'accounts' => $results]);
break;
case 'status':
$s = pg_fetch_assoc(pg_query($db, "
SELECT
(SELECT COUNT(*) FROM cloudflare_accounts WHERE status='active') as total_accounts,
(SELECT COUNT(*) FROM cloudflare_accounts WHERE api_key IS NOT NULL AND api_key!='') as with_keys,
(SELECT COUNT(*) FROM cloudflare_accounts WHERE api_key IS NULL OR api_key='') as needs_keys,
(SELECT COUNT(*) FROM cloudflare_domains) as total_domains,
(SELECT SUM(domains_count) FROM cloudflare_accounts) as reported_domains
"));
echo json_encode(['status' => 'success', 'stats' => $s]);
break;
}