HeatiaCP-API-SSL/BAK/index copy.js

266 lines
5.4 KiB
JavaScript
Executable File

// server.mjs (or server.js with "type": "module")
import express from "express";
import axios from "axios";
import https from "https";
// 👉 Environment / Secrets
const API = process.env.HESTIA_API_HASH || "vvQjauyYQ2YDY2Au-_DC4QO5MUPFiHNn";
const SERVER = process.env.HESTIA_SERVER_URL || "https://host.metatronhost.com:8083/api/";
// 👉 FIXED Hestia username
const HESTIA_USER = "user";
// Ignore self-signed SSL
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
// ===============================
// 🔧 H E S T I A H E L P E R S
// ===============================
async function hestia(cmd, args = {}) {
const form = new URLSearchParams({
hash: API,
cmd,
...args,
});
const res = await axios.post(SERVER, form, { httpsAgent });
return res.data;
}
// Fetch raw DNS domain table
async function getRawDomainList() {
const form = new URLSearchParams({
hash: API,
cmd: "v-list-dns-domains",
arg1: HESTIA_USER,
});
const res = await axios.post(SERVER, form, { httpsAgent });
return res.data;
}
// Parse domains from raw table
function parseDomainsFromTable(text) {
const lines = text.split("\n");
const domains = [];
for (let line of lines) {
line = line.trim();
if (!line.includes(".")) continue;
if (line.startsWith("DOMAIN")) continue;
if (line.startsWith("------")) continue;
const parts = line.split(/\s+/);
const domain = parts[0];
if (domain && domain.includes(".")) {
domains.push(domain);
}
}
return domains;
}
// Remove SSL certificate
async function removeSsl(domain) {
return hestia("v-delete-web-domain-ssl", {
arg1: HESTIA_USER,
arg2: domain,
});
}
// Add Let's Encrypt SSL
async function addSsl(domain) {
return hestia("v-add-letsencrypt-domain", {
arg1: HESTIA_USER,
arg2: domain,
});
}
// Remove + Add (renew)
async function refreshSsl(domain) {
const removed = await removeSsl(domain);
const added = await addSsl(domain);
return { removed, added };
}
function parseRawTable(text) {
const lines = text.split("\n").map(l => l.trim()).filter(Boolean);
const dataRows = [];
// Skip first 2 header lines
for (let i = 2; i < lines.length; i++) {
const line = lines[i];
const parts = line.split(/\s+/);
// Expect at least 8 columns
if (parts.length < 8) continue;
const [
domain,
ip,
tpl,
ttl,
dnssec,
rec,
spnd,
date
] = parts;
dataRows.push({
domain,
ip,
tpl,
ttl: Number(ttl),
dnssec,
rec: Number(rec),
spnd,
date
});
}
return dataRows;
}
// ===============================
// 🚀 E X P R E S S A P I
// ===============================
const app = express();
app.use(express.json());
// Health
app.get("/", (req, res) => {
res.json({ running: true, user: HESTIA_USER });
});
// Get all DNS domains
app.get("/dns/domains", async (req, res) => {
try {
const raw = await getRawDomainList();
const domains = parseDomainsFromTable(raw);
const rawParsed = parseRawTable(raw);
res.json({
success: true,
domains,
rawParsed
});
} catch (err) {
res.status(500).json({
success: false,
error: err.response?.data || err.message
});
}
});
// Remove SSL
app.post("/ssl/remove", async (req, res) => {
const { domain } = req.body;
if (!domain) {
return res.status(400).json({ success: false, error: "domain is required" });
}
try {
const result = await removeSsl(domain);
res.json({ success: true, domain, result });
} catch (err) {
res.status(500).json({
success: false,
domain,
error: err.response?.data || err.message,
});
}
});
// Add SSL
app.post("/ssl/add", async (req, res) => {
const { domain } = req.body;
if (!domain) {
return res.status(400).json({ success: false, error: "domain is required" });
}
try {
const result = await addSsl(domain);
res.json({ success: true, domain, result });
} catch (err) {
res.status(500).json({
success: false,
domain,
error: err.response?.data || err.message,
});
}
});
// Refresh SSL
app.post("/ssl/refresh", async (req, res) => {
const { domain } = req.body;
if (!domain) {
return res.status(400).json({ success: false, error: "domain is required" });
}
try {
const result = await refreshSsl(domain);
res.json({ success: true, domain, result });
} catch (err) {
res.status(500).json({
success: false,
domain,
error: err.response?.data || err.message,
});
}
});
// Refresh SSL for ALL domains
app.post("/ssl/refresh-all", async (req, res) => {
try {
const raw = await getRawDomainList();
const domains = parseDomainsFromTable(raw);
const results = [];
for (const domain of domains) {
try {
const result = await refreshSsl(domain);
results.push({ domain, success: true, result });
} catch (e) {
results.push({
domain,
success: false,
error: e.response?.data || e.message,
});
}
}
res.json({
success: true,
user: HESTIA_USER,
results,
});
} catch (err) {
res.status(500).json({
success: false,
error: err.response?.data || err.message,
});
}
});
// Start server
const PORT = process.env.PORT || 3015;
app.listen(PORT, () => {
console.log(`🔥 SSL Manager API running at port ${PORT}`);
});