Files
ignis/apps/ignis-server/server/routes/settings.js
2026-06-06 13:04:34 +02:00

93 lines
2.0 KiB
JavaScript

const express = require("express");
const { writeCoalescer } = require("@ignis/server-core");
const settings = require("../settings");
const bootstrapRoutes = require("./bootstrap");
const router = express.Router();
const NUMBER_KEYS = [
"contentCacheBytes",
"inputCacheBytes",
"inputCacheTtlMs",
"writeCoalesceMs",
"maxBodyBytes",
];
const LIST_KEYS = ["proxyAllowlist", "wsOrigins"];
function validate(body) {
const clean = {};
for (const key of NUMBER_KEYS) {
if (body[key] === undefined) {
continue;
}
const n = body[key];
if (!Number.isInteger(n) || n < 0) {
throw new Error(`${key} must be a non-negative integer`);
}
if (key === "maxBodyBytes" && (n < 1 || n > settings.MAX_BODY_BACKSTOP)) {
throw new Error(
`maxBodyBytes must be between 1 and ${settings.MAX_BODY_BACKSTOP}`,
);
}
clean[key] = n;
}
for (const key of LIST_KEYS) {
if (body[key] === undefined) {
continue;
}
const list = body[key];
if (
!Array.isArray(list) ||
list.some((v) => typeof v !== "string" || !v.trim())
) {
throw new Error(`${key} must be an array of non-empty strings`);
}
clean[key] = list.map((v) => v.trim());
}
return clean;
}
function applySettings(effective, req) {
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) => {
res.json(settings.getAll());
});
router.post("/", (req, res) => {
let clean;
try {
clean = validate(req.body || {});
} catch (e) {
return res.status(400).json({ error: e.message });
}
const effective = settings.update(clean);
applySettings(effective, req);
// Cache sizes ride in the bootstrap response; clear it so the next page load picks up new values.
bootstrapRoutes.invalidateAll();
res.json(effective);
});
module.exports = router;