mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
add server settings store
This commit is contained in:
@@ -75,16 +75,6 @@ module.exports = {
|
|||||||
vaults = discoverVaults();
|
vaults = discoverVaults();
|
||||||
return vaults;
|
return vaults;
|
||||||
},
|
},
|
||||||
writeCoalesceMs:
|
|
||||||
process.env.WRITE_COALESCE_MS !== undefined
|
|
||||||
? parseInt(process.env.WRITE_COALESCE_MS)
|
|
||||||
: 5000,
|
|
||||||
|
|
||||||
wsOrigins: process.env.WS_ORIGINS
|
|
||||||
? process.env.WS_ORIGINS.split(",")
|
|
||||||
.map((s) => s.trim())
|
|
||||||
.filter(Boolean)
|
|
||||||
: null,
|
|
||||||
|
|
||||||
demoMode: process.env.DEMO_MODE === "true",
|
demoMode: process.env.DEMO_MODE === "true",
|
||||||
demoMaxSessions: parseInt(process.env.DEMO_MAX_SESSIONS) || 20,
|
demoMaxSessions: parseInt(process.env.DEMO_MAX_SESSIONS) || 20,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const fs = require("fs");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const compression = require("compression");
|
const compression = require("compression");
|
||||||
const config = require("./config");
|
const config = require("./config");
|
||||||
|
const settings = require("./settings");
|
||||||
const { getVersion } = require("./version");
|
const { getVersion } = require("./version");
|
||||||
const {
|
const {
|
||||||
setupWebSocket,
|
setupWebSocket,
|
||||||
@@ -19,7 +20,7 @@ const {
|
|||||||
getBundledPluginDirs,
|
getBundledPluginDirs,
|
||||||
} = require("./plugin-system/manager");
|
} = require("./plugin-system/manager");
|
||||||
const pluginRoutes = require("./routes/plugins");
|
const pluginRoutes = require("./routes/plugins");
|
||||||
writeCoalescer.configure({ writeCoalesceMs: config.writeCoalesceMs });
|
writeCoalescer.configure({ writeCoalesceMs: settings.get("writeCoalesceMs") });
|
||||||
const { flushAll } = writeCoalescer;
|
const { flushAll } = writeCoalescer;
|
||||||
const { setupDemo, wireDemoWebSocket } = require("./demo");
|
const { setupDemo, wireDemoWebSocket } = require("./demo");
|
||||||
|
|
||||||
@@ -197,7 +198,7 @@ const server = app.listen(config.port, async () => {
|
|||||||
|
|
||||||
const wss = setupWebSocket(server, {
|
const wss = setupWebSocket(server, {
|
||||||
getVaultPath: config.getVaultPath,
|
getVaultPath: config.getVaultPath,
|
||||||
originAllowlist: config.wsOrigins,
|
originAllowlist: settings.get("wsOrigins"),
|
||||||
});
|
});
|
||||||
wireDemoWebSocket(server);
|
wireDemoWebSocket(server);
|
||||||
|
|
||||||
|
|||||||
91
apps/ignis-server/server/settings.js
Normal file
91
apps/ignis-server/server/settings.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const config = require("./config");
|
||||||
|
|
||||||
|
// Runtime server settings set through UI.
|
||||||
|
|
||||||
|
const SETTINGS_FILE = path.join(config.dataRoot, "server-settings.json");
|
||||||
|
|
||||||
|
const DEFAULTS = {
|
||||||
|
contentCacheBytes: 50 * 1024 * 1024,
|
||||||
|
inputCacheBytes: 200 * 1024 * 1024,
|
||||||
|
inputCacheTtlMs: 5 * 60 * 1000,
|
||||||
|
writeCoalesceMs: 5000,
|
||||||
|
maxBodyBytes: 50 * 1024 * 1024,
|
||||||
|
// Empty arrays mean "no restriction": any proxy host, any WS origin.
|
||||||
|
proxyAllowlist: [],
|
||||||
|
wsOrigins: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const KEYS = Object.keys(DEFAULTS);
|
||||||
|
|
||||||
|
function parseList(raw) {
|
||||||
|
return raw
|
||||||
|
.split(",")
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromEnv() {
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
if (process.env.WRITE_COALESCE_MS !== undefined) {
|
||||||
|
const n = parseInt(process.env.WRITE_COALESCE_MS, 10);
|
||||||
|
|
||||||
|
if (Number.isFinite(n)) {
|
||||||
|
env.writeCoalesceMs = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.WS_ORIGINS) {
|
||||||
|
env.wsOrigins = parseList(process.env.WS_ORIGINS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
const envOverrides = fromEnv();
|
||||||
|
|
||||||
|
function loadFile() {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(fs.readFileSync(SETTINGS_FILE, "utf-8"));
|
||||||
|
// Keep only known keys so a stale or hand-edited file can't inject junk.
|
||||||
|
const clean = {};
|
||||||
|
|
||||||
|
for (const key of KEYS) {
|
||||||
|
if (parsed[key] !== undefined) {
|
||||||
|
clean[key] = parsed[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clean;
|
||||||
|
} catch {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileOverrides = loadFile();
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
return { ...DEFAULTS, ...envOverrides, ...fileOverrides };
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(key) {
|
||||||
|
return getAll()[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)) {
|
||||||
|
fileOverrides[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.mkdirSync(path.dirname(SETTINGS_FILE), { recursive: true });
|
||||||
|
fs.writeFileSync(SETTINGS_FILE, JSON.stringify(fileOverrides, null, 2));
|
||||||
|
|
||||||
|
return getAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { DEFAULTS, KEYS, getAll, get, update };
|
||||||
@@ -2,6 +2,11 @@ const { WebSocketServer } = require("ws");
|
|||||||
const url = require("url");
|
const url = require("url");
|
||||||
const watcher = require("./watcher");
|
const watcher = require("./watcher");
|
||||||
|
|
||||||
|
// Null / undefined / empty array means no Origin check.
|
||||||
|
function toOriginSet(list) {
|
||||||
|
return Array.isArray(list) && list.length > 0 ? new Set(list) : null;
|
||||||
|
}
|
||||||
|
|
||||||
function setupWebSocket(server, opts = {}) {
|
function setupWebSocket(server, opts = {}) {
|
||||||
const { getVaultPath, originAllowlist } = opts;
|
const { getVaultPath, originAllowlist } = opts;
|
||||||
|
|
||||||
@@ -9,14 +14,14 @@ function setupWebSocket(server, opts = {}) {
|
|||||||
throw new Error("setupWebSocket: opts.getVaultPath is required");
|
throw new Error("setupWebSocket: opts.getVaultPath is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Null / undefined / empty array = no Origin check.
|
let originSet = toOriginSet(originAllowlist);
|
||||||
const originSet =
|
|
||||||
Array.isArray(originAllowlist) && originAllowlist.length > 0
|
|
||||||
? new Set(originAllowlist)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const wss = new WebSocketServer({ server, path: "/ws" });
|
const wss = new WebSocketServer({ server, path: "/ws" });
|
||||||
|
|
||||||
|
wss.setOriginAllowlist = function (list) {
|
||||||
|
originSet = toOriginSet(list);
|
||||||
|
};
|
||||||
|
|
||||||
// Global message handlers: type -> handler(msg, ws).
|
// Global message handlers: type -> handler(msg, ws).
|
||||||
wss.messageHandlers = new Map();
|
wss.messageHandlers = new Map();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user