123 lines
3.9 KiB
JavaScript
123 lines
3.9 KiB
JavaScript
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}`));
|