import { Client, Databases } from 'node-appwrite'; const APPWRITE_ENDPOINT = process.env.APPWRITE_ENDPOINT || process.env.APPWRITE_FUNCTION_ENDPOINT; const APPWRITE_PROJECT_ID = process.env.APPWRITE_PROJECT_ID || process.env.APPWRITE_FUNCTION_PROJECT_ID; const APPWRITE_API_KEY = process.env.APPWRITE_API_KEY; const DATABASE_ID = process.env.APPWRITE_DATABASE_ID; const cfHeaders = (token) => ({ Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' }); async function fetchZones(token, log) { const response = await fetch('https://api.cloudflare.com/client/v4/zones', { headers: cfHeaders(token) }); if (!response.ok) { const body = await response.text(); log(`Cloudflare zones error: ${body}`); throw new Error('Failed to fetch Cloudflare zones'); } const { result } = await response.json(); return result.map((zone) => ({ id: zone.id, name: zone.name, status: zone.status, paused: zone.paused })); } async function fetchWorkers(token, accountId, log) { if (!accountId) return []; const response = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/scripts`, { headers: cfHeaders(token) }); if (!response.ok) { const body = await response.text(); log(`Cloudflare workers error: ${body}`); throw new Error('Failed to fetch Cloudflare workers'); } const { result } = await response.json(); return result.map((worker) => ({ name: worker.name, modifiedOn: worker.modified_on, active: worker.created_on !== undefined })); } export default async function ({ req, res, log, error }) { try { if (!APPWRITE_ENDPOINT || !APPWRITE_PROJECT_ID || !APPWRITE_API_KEY || !DATABASE_ID) { return res.json({ error: 'Missing Appwrite environment configuration.' }, 500); } const payload = req.body ? JSON.parse(req.body) : {}; const accountId = payload.accountId; const requesterId = (req.headers && (req.headers['x-appwrite-user-id'] || req.headers['x-appwrite-userid'])) || process.env.APPWRITE_FUNCTION_USER_ID || payload.userId; if (!accountId) { return res.json({ error: 'accountId is required in the request body.' }, 400); } const client = new Client() .setEndpoint(APPWRITE_ENDPOINT) .setProject(APPWRITE_PROJECT_ID) .setKey(APPWRITE_API_KEY); const databases = new Databases(client); const account = await databases.getDocument(DATABASE_ID, 'cloud_accounts', accountId); if (!account || account.provider !== 'cloudflare') { return res.json({ error: 'Cloud account not found or not a Cloudflare credential.' }, 404); } if (account.userId && requesterId && account.userId !== requesterId) { return res.json({ error: 'You are not allowed to use this credential.' }, 403); } const token = account.apiKey; if (!token) { return res.json({ error: 'Cloudflare token is missing for this account.' }, 400); } const cloudflareAccountId = payload.cloudflareAccountId || account.cloudflareAccountId; const [zones, workers] = await Promise.all([ fetchZones(token, log), fetchWorkers(token, cloudflareAccountId, log) ]); return res.json({ zones, workers, message: workers.length ? 'Zones and Workers status fetched successfully.' : 'Zones status fetched successfully.' }); } catch (err) { error(err.message); return res.json({ error: 'Unexpected error while checking Cloudflare status.' }, 500); } }