import express from 'express'; import cors from 'cors'; import { readFileSync, writeFileSync, existsSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __dirname = dirname(fileURLToPath(import.meta.url)); const CONFIG_FILE = join(__dirname, 'config.json'); const app = express(); app.use(cors()); app.use(express.json()); function loadConfig() { if (!existsSync(CONFIG_FILE)) return { hostinger_api_key: '' }; try { return JSON.parse(readFileSync(CONFIG_FILE, 'utf8')); } catch { return { hostinger_api_key: '' }; } } function saveConfig(data) { writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8'); } // GET configuração (mascara a key) app.get('/api/config', (req, res) => { const cfg = loadConfig(); res.json({ has_api_key: !!cfg.hostinger_api_key }); }); // POST salvar API key da Hostinger app.post('/api/config/hostinger-key', (req, res) => { const { api_key } = req.body; if (!api_key?.trim()) return res.status(400).json({ error: 'api_key obrigatória' }); const cfg = loadConfig(); cfg.hostinger_api_key = api_key.trim(); saveConfig(cfg); res.json({ ok: true }); }); // GET listar domínios via Hostinger API (Corrigido para v1/portfolio) app.get('/api/subdomains', async (req, res) => { const cfg = loadConfig(); console.log('[BACKEND] Buscando domínios na Hostinger...'); if (!cfg.hostinger_api_key) return res.status(400).json({ error: 'API key não configurada' }); try { const r = await fetch('https://developers.hostinger.com/api/domains/v1/portfolio', { headers: { 'Authorization': `Bearer ${cfg.hostinger_api_key}`, 'Accept': 'application/json' } }); console.log('[BACKEND] Status Hostinger:', r.status); if (!r.ok) { const errText = await r.text(); console.error('[BACKEND] Erro Hostinger:', errText); return res.status(r.status).json({ error: `Hostinger Error: ${r.status}` }); } const data = await r.json(); console.log('[BACKEND] Domínios encontrados:', Array.isArray(data) ? data.length : 'Não é array'); res.json(data); } catch (e) { console.error('[BACKEND] Crash fetch:', e.message); res.status(500).json({ error: e.message }); } }); // POST criar subdomínio no DNS da Hostinger (Corrigido para v1/zones/{domain}) app.post('/api/subdomains', async (req, res) => { const cfg = loadConfig(); if (!cfg.hostinger_api_key) return res.status(400).json({ error: 'API key não configurada' }); const { domain, subdomain, type = 'A', value } = req.body; console.log(`[BACKEND] Criando subdomínio ${subdomain}.${domain} -> ${value}`); if (!domain || !subdomain || !value) return res.status(400).json({ error: 'domain, subdomain e value obrigatórios' }); try { const r = await fetch(`https://developers.hostinger.com/api/dns/v1/zones/${domain}`, { method: 'PUT', headers: { 'Authorization': `Bearer ${cfg.hostinger_api_key}`, 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ overwrite: false, zone: [ { name: subdomain, type: type, records: [ { content: value, ttl: 300 } ] } ] }) }); console.log('[BACKEND] Status Criação DNS:', r.status); if (!r.ok) { const errText = await r.text(); console.error('[BACKEND] Erro Criação DNS:', errText); return res.status(r.status).json({ error: `Erro DNS: ${r.status}` }); } const data = await r.json(); res.json({ ok: true, data }); } catch (e) { console.error('[BACKEND] Crash Criação DNS:', e.message); res.status(500).json({ error: e.message }); } }); const PORT = process.env.PORT || 8019; app.listen(PORT, () => console.log(`[subdominio-backend] porta ${PORT}`));