176 lines
4.7 KiB
JavaScript
176 lines
4.7 KiB
JavaScript
const express = require("express");
|
|
const puppeteer = require("puppeteer");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const app = express();
|
|
const fetch = require("node-fetch");
|
|
|
|
app.use(express.json());
|
|
app.use(express.static("public"));
|
|
|
|
// ========== Global token store ==========
|
|
let globalAuth = {
|
|
csrfToken: null,
|
|
cookieHeader: null
|
|
};
|
|
|
|
const OPENSENCE_DOMAIN = "http://192.168.1.1/"
|
|
// ========== Auto login with Puppeteer ==========
|
|
async function refreshLoginSession() {
|
|
console.log("🔐 Refreshing login session...");
|
|
const browser = await puppeteer.launch({
|
|
headless: true,
|
|
args: ["--no-sandbox"]
|
|
});
|
|
|
|
const page = await browser.newPage();
|
|
const opnUrl = OPENSENCE_DOMAIN;
|
|
const username = "root";
|
|
const password = "opnsense";
|
|
|
|
try {
|
|
await page.goto(opnUrl, { waitUntil: "networkidle2" });
|
|
|
|
const csrf = await page.$eval('form input[type="hidden"]', input => ({
|
|
name: input.name,
|
|
value: input.value
|
|
}));
|
|
|
|
await page.type("#usernamefld", username);
|
|
await page.type("#passwordfld", password);
|
|
await page.click(".btn");
|
|
|
|
setTimeout(async()=>{
|
|
const cookies = await page.cookies();
|
|
const cookieHeader = cookies.map(c => `${c.name}=${c.value}`).join("; ");
|
|
globalAuth.csrfToken = csrf.value;
|
|
globalAuth.cookieHeader = cookieHeader;
|
|
await browser.close();
|
|
console.log("✅ Login refreshed!");
|
|
}, 2000)
|
|
|
|
|
|
} catch (err) {
|
|
console.error("❌ Login failed:", err.message);
|
|
}
|
|
}
|
|
|
|
// Run once immediately, then every 5 minutes
|
|
refreshLoginSession();
|
|
setInterval(refreshLoginSession, 5 * 60 * 1000);
|
|
|
|
// ========== API Routes ==========
|
|
|
|
app.get("/", (req, res) => {
|
|
res.sendFile(path.join(__dirname, "public", "index.html"));
|
|
});
|
|
|
|
// GET /api/getListApp
|
|
app.get("/api/getListApp", async (req, res) => {
|
|
const filePath = path.join(__dirname, "listApp.txt");
|
|
try {
|
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
const apps = JSON.parse(content);
|
|
|
|
// Gọi API để lấy init từ policy detail
|
|
const policyRes = await fetch(OPENSENCE_DOMAIN+"api/zenarmor/policy/detail?id=0", {
|
|
headers: {
|
|
"Accept": "application/json",
|
|
"Cookie": globalAuth.cookieHeader,
|
|
"X-CSRFTOKEN": globalAuth.csrfToken
|
|
}
|
|
});
|
|
const policyJson = await policyRes.json();
|
|
const init = policyJson.app_controls || [];
|
|
|
|
res.json({ data: apps, init });
|
|
} catch (err) {
|
|
console.error("❌ Error in /api/getListApp:", JSON.stringify(err));
|
|
res.status(500).json({ error: "Failed to load apps" });
|
|
}
|
|
});
|
|
|
|
// POST /update
|
|
app.post("/update", async (req, res) => {
|
|
const { app_ids } = req.body;
|
|
if (!Array.isArray(app_ids)) {
|
|
return res.status(400).json({ error: "app_ids must be an array" });
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(OPENSENCE_DOMAIN+"api/zenarmor/policy/apply", {
|
|
method: "POST",
|
|
headers: {
|
|
"Accept": "*/*",
|
|
"Content-Type": "application/json",
|
|
"X-CSRFTOKEN": globalAuth.csrfToken,
|
|
"Cookie": globalAuth.cookieHeader
|
|
},
|
|
body: JSON.stringify({
|
|
id: "0",
|
|
checksum: 0,
|
|
cloud_id: 0,
|
|
is_active: true,
|
|
is_centralized: false,
|
|
is_default: false,
|
|
name: "Default",
|
|
decision_is_block: false,
|
|
block_untrusted_devices: false,
|
|
groups: [],
|
|
usernames: [],
|
|
interfaces: [],
|
|
vlans: [],
|
|
devices: [],
|
|
device_categories: [],
|
|
mac_addresses: [],
|
|
networks: [],
|
|
directions: {
|
|
inbound: false,
|
|
outbound: false
|
|
},
|
|
webcategory_type: "permissive",
|
|
sort_number: 0,
|
|
security: false,
|
|
app: true,
|
|
web: false,
|
|
tls: false,
|
|
advanced_security: [],
|
|
essential_security: [],
|
|
app_controls: app_ids,
|
|
app_controls_custom: [],
|
|
web_controls: [],
|
|
web_controls_custom: ["b665988a-05ed-4c7e-8964-50459265e8c9"],
|
|
url_blocks: [],
|
|
safe_search: "off",
|
|
block_ech: true,
|
|
schedules: [],
|
|
tls_controls: {
|
|
enabled: false,
|
|
ignore_pinned_certs: false,
|
|
lazy_inspection: false,
|
|
webs_all: false,
|
|
webs: []
|
|
},
|
|
casb: {
|
|
actions: []
|
|
},
|
|
exclusion_blacklist: [],
|
|
exclusion_whitelist: [],
|
|
exclusion_blacklist_global: [],
|
|
exclusion_whitelist_global: []
|
|
})
|
|
});
|
|
|
|
const result = await response.text();
|
|
res.json({ success: true, result });
|
|
} catch (err) {
|
|
console.error("❌ Error in /update:", err.message);
|
|
res.status(500).json({ error: "Failed to apply policy" });
|
|
}
|
|
});
|
|
|
|
const PORT = 3000;
|
|
app.listen(PORT, () => {
|
|
console.log(`🚀 Server running at http://localhost:${PORT}`);
|
|
});
|