mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
add server settings UI and enforcement
This commit is contained in:
@@ -213,7 +213,6 @@ const wss = setupWebSocket(server, {
|
||||
getVaultPath: config.getVaultPath,
|
||||
originAllowlist: settings.get("wsOrigins"),
|
||||
});
|
||||
app.set("wss", wss);
|
||||
wireDemoWebSocket(server);
|
||||
|
||||
async function gracefulShutdown(signal) {
|
||||
|
||||
@@ -100,16 +100,20 @@ router.post("/", async (req, res) => {
|
||||
return res.status(400).json({ error: "Missing url" });
|
||||
}
|
||||
|
||||
const proxyMode = settings.get("proxyMode");
|
||||
|
||||
if (proxyMode === "disabled") {
|
||||
return res.status(403).json({ error: "Proxy is disabled" });
|
||||
}
|
||||
|
||||
try {
|
||||
await assertPublicUrl(url);
|
||||
} catch (e) {
|
||||
return res.status(e.statusCode || 400).json({ error: e.message });
|
||||
}
|
||||
|
||||
// When a host allowlist is defined , the proxy only reaches those hosts.
|
||||
const allowlist = settings.get("proxyAllowlist");
|
||||
|
||||
if (allowlist.length > 0) {
|
||||
if (proxyMode === "allowlist") {
|
||||
const allowlist = settings.get("proxyAllowlist");
|
||||
const host = new URL(url).hostname;
|
||||
|
||||
if (!allowlist.includes(host)) {
|
||||
|
||||
@@ -12,11 +12,21 @@ const NUMBER_KEYS = [
|
||||
"writeCoalesceMs",
|
||||
"maxBodyBytes",
|
||||
];
|
||||
const LIST_KEYS = ["proxyAllowlist", "wsOrigins"];
|
||||
const LIST_KEYS = ["proxyAllowlist"];
|
||||
|
||||
function validate(body) {
|
||||
const clean = {};
|
||||
|
||||
if (body.proxyMode !== undefined) {
|
||||
if (!settings.PROXY_MODES.includes(body.proxyMode)) {
|
||||
throw new Error(
|
||||
`proxyMode must be one of: ${settings.PROXY_MODES.join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
clean.proxyMode = body.proxyMode;
|
||||
}
|
||||
|
||||
for (const key of NUMBER_KEYS) {
|
||||
if (body[key] === undefined) {
|
||||
continue;
|
||||
@@ -57,14 +67,8 @@ function validate(body) {
|
||||
return clean;
|
||||
}
|
||||
|
||||
function applySettings(effective, req) {
|
||||
function applySettings(effective) {
|
||||
writeCoalescer.configure({ writeCoalesceMs: effective.writeCoalesceMs });
|
||||
|
||||
const wss = req.app.get("wss");
|
||||
|
||||
if (wss && typeof wss.setOriginAllowlist === "function") {
|
||||
wss.setOriginAllowlist(effective.wsOrigins);
|
||||
}
|
||||
}
|
||||
|
||||
router.get("/", (req, res) => {
|
||||
@@ -81,7 +85,7 @@ router.post("/", (req, res) => {
|
||||
}
|
||||
|
||||
const effective = settings.update(clean);
|
||||
applySettings(effective, req);
|
||||
applySettings(effective);
|
||||
|
||||
// Cache sizes ride in the bootstrap response; clear it so the next page load picks up new values.
|
||||
bootstrapRoutes.invalidateAll();
|
||||
|
||||
@@ -12,13 +12,20 @@ const DEFAULTS = {
|
||||
inputCacheTtlMs: 5 * 60 * 1000,
|
||||
writeCoalesceMs: 5000,
|
||||
maxBodyBytes: 50 * 1024 * 1024,
|
||||
// Empty arrays mean "no restriction": any proxy host, any WS origin.
|
||||
// "any" reaches any public host, "allowlist" restricts to proxyAllowlist, "disabled" blocks all proxying.
|
||||
proxyMode: "any",
|
||||
// Empty allows any public host.
|
||||
proxyAllowlist: [],
|
||||
wsOrigins: [],
|
||||
};
|
||||
|
||||
const PROXY_MODES = ["any", "allowlist", "disabled"];
|
||||
|
||||
const KEYS = Object.keys(DEFAULTS);
|
||||
|
||||
// Env vars only; never persisted to the settings file.
|
||||
const ENV_ONLY_KEYS = ["wsOrigins"];
|
||||
|
||||
// Hard ceiling for request bodies.
|
||||
const MAX_BODY_BACKSTOP = 500 * 1024 * 1024;
|
||||
|
||||
@@ -56,6 +63,10 @@ function loadFile() {
|
||||
const clean = {};
|
||||
|
||||
for (const key of KEYS) {
|
||||
if (ENV_ONLY_KEYS.includes(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parsed[key] !== undefined) {
|
||||
clean[key] = parsed[key];
|
||||
}
|
||||
@@ -80,7 +91,7 @@ function get(key) {
|
||||
// Merge validated changes into the persisted file and return the new effective settings.
|
||||
function update(partial) {
|
||||
for (const [key, value] of Object.entries(partial)) {
|
||||
if (KEYS.includes(key)) {
|
||||
if (KEYS.includes(key) && !ENV_ONLY_KEYS.includes(key)) {
|
||||
fileOverrides[key] = value;
|
||||
}
|
||||
}
|
||||
@@ -91,4 +102,13 @@ function update(partial) {
|
||||
return getAll();
|
||||
}
|
||||
|
||||
module.exports = { DEFAULTS, KEYS, MAX_BODY_BACKSTOP, getAll, get, update };
|
||||
module.exports = {
|
||||
DEFAULTS,
|
||||
KEYS,
|
||||
ENV_ONLY_KEYS,
|
||||
PROXY_MODES,
|
||||
MAX_BODY_BACKSTOP,
|
||||
getAll,
|
||||
get,
|
||||
update,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user