fix(webui): require administrator permissions to change server config

This commit is contained in:
Sainan 2024-12-23 19:34:39 +01:00
parent 6e27eea7bb
commit d8956faed2
4 changed files with 118 additions and 90 deletions

View File

@ -1,8 +1,14 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { config } from "@/src/services/configService"; import { config } from "@/src/services/configService";
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
const getConfigDataController: RequestHandler = (_req, res) => { const getConfigDataController: RequestHandler = async (req, res) => {
res.json(config); const account = await getAccountForRequest(req);
if (isAdministrator(account)) {
res.json(config);
} else {
res.status(401).end();
}
}; };
export { getConfigDataController }; export { getConfigDataController };

View File

@ -1,9 +1,15 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { updateConfig } from "@/src/services/configService"; import { updateConfig } from "@/src/services/configService";
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
const updateConfigDataController: RequestHandler = async (req, res) => { const updateConfigDataController: RequestHandler = async (req, res) => {
await updateConfig(String(req.body)); const account = await getAccountForRequest(req);
res.end(); if (isAdministrator(account)) {
await updateConfig(String(req.body));
res.end();
} else {
res.status(401).end();
}
}; };
export { updateConfigDataController }; export { updateConfigDataController };

View File

@ -198,75 +198,80 @@
<div class="col-lg-4"> <div class="col-lg-4">
<div class="card mb-4"> <div class="card mb-4">
<h5 class="card-header">Server</h5> <h5 class="card-header">Server</h5>
<form class="card-body" onsubmit="doChangeSettings();return false;"> <div class="card-body">
<div class="form-check"> <div id="server-settings-no-perms" class="d-none">
<input class="form-check-input" type="checkbox" id="skipStoryModeChoice" /> <p>You must be an administrator to use this feature. To become an administrator, add <code>"<span class="displayname"></span>"</code> to <code>administratorNames</code> in the config.json.</p>
<label class="form-check-label" for="skipStoryModeChoice">Skip Story Mode Choice</label>
</div> </div>
<div class="form-check"> <form id="server-settings" class="d-none" onsubmit="doChangeSettings();return false;">
<input class="form-check-input" type="checkbox" id="skipTutorial" /> <div class="form-check">
<label class="form-check-label" for="skipTutorial">Skip Tutorial</label> <input class="form-check-input" type="checkbox" id="skipStoryModeChoice" />
</div> <label class="form-check-label" for="skipStoryModeChoice">Skip Story Mode Choice</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="skipAllDialogue" /> <div class="form-check">
<label class="form-check-label" for="skipAllDialogue">Skip All Dialogue</label> <input class="form-check-input" type="checkbox" id="skipTutorial" />
</div> <label class="form-check-label" for="skipTutorial">Skip Tutorial</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="unlockAllScans" /> <div class="form-check">
<label class="form-check-label" for="unlockAllScans">Unlock All Scans</label> <input class="form-check-input" type="checkbox" id="skipAllDialogue" />
</div> <label class="form-check-label" for="skipAllDialogue">Skip All Dialogue</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="unlockAllMissions" /> <div class="form-check">
<label class="form-check-label" for="unlockAllMissions">Unlock All Missions</label> <input class="form-check-input" type="checkbox" id="unlockAllScans" />
</div> <label class="form-check-label" for="unlockAllScans">Unlock All Scans</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="unlockAllQuests" /> <div class="form-check">
<label class="form-check-label" for="unlockAllQuests">Unlock All Quests</label> <input class="form-check-input" type="checkbox" id="unlockAllMissions" />
</div> <label class="form-check-label" for="unlockAllMissions">Unlock All Missions</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="completeAllQuests" /> <div class="form-check">
<label class="form-check-label" for="completeAllQuests">Complete All Quests</label> <input class="form-check-input" type="checkbox" id="unlockAllQuests" />
</div> <label class="form-check-label" for="unlockAllQuests">Unlock All Quests</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="infiniteCredits" /> <div class="form-check">
<label class="form-check-label" for="infiniteCredits">Infinite Credits</label> <input class="form-check-input" type="checkbox" id="completeAllQuests" />
</div> <label class="form-check-label" for="completeAllQuests">Complete All Quests</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="infinitePlatinum" /> <div class="form-check">
<label class="form-check-label" for="infinitePlatinum">Infinite Platinum</label> <input class="form-check-input" type="checkbox" id="infiniteCredits" />
</div> <label class="form-check-label" for="infiniteCredits">Infinite Credits</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" /> <div class="form-check">
<label class="form-check-label" for="unlockAllShipFeatures">Unlock All Ship Features</label> <input class="form-check-input" type="checkbox" id="infinitePlatinum" />
</div> <label class="form-check-label" for="infinitePlatinum">Infinite Platinum</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="unlockAllShipDecorations" /> <div class="form-check">
<label class="form-check-label" for="unlockAllShipDecorations">Unlock All Ship Decorations</label> <input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" />
</div> <label class="form-check-label" for="unlockAllShipFeatures">Unlock All Ship Features</label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="unlockAllFlavourItems" /> <div class="form-check">
<label class="form-check-label" for="unlockAllFlavourItems"> <input class="form-check-input" type="checkbox" id="unlockAllShipDecorations" />
Unlock All <abbr title="Animation Sets, Glyphs, Plattes, etc.">Flavor Items</abbr> <label class="form-check-label" for="unlockAllShipDecorations">Unlock All Ship Decorations</label>
</label> </div>
</div> <div class="form-check">
<div class="form-check"> <input class="form-check-input" type="checkbox" id="unlockAllFlavourItems" />
<input class="form-check-input" type="checkbox" id="unlockAllSkins" /> <label class="form-check-label" for="unlockAllFlavourItems">
<label class="form-check-label" for="unlockAllSkins">Unlock All Skins</label> Unlock All <abbr title="Animation Sets, Glyphs, Plattes, etc.">Flavor Items</abbr>
</div> </label>
<div class="form-check"> </div>
<input class="form-check-input" type="checkbox" id="universalPolarityEverywhere" /> <div class="form-check">
<label class="form-check-label" for="universalPolarityEverywhere"> <input class="form-check-input" type="checkbox" id="unlockAllSkins" />
Universal Polarity Everywhere <label class="form-check-label" for="unlockAllSkins">Unlock All Skins</label>
</label> </div>
</div> <div class="form-check">
<div class="form-group mt-2"> <input class="form-check-input" type="checkbox" id="universalPolarityEverywhere" />
<label class="form-label" for="spoofMasteryRank"> <label class="form-check-label" for="universalPolarityEverywhere">
Spoofed Mastery Rank (-1 to disable) Universal Polarity Everywhere
</label> </label>
<input class="form-control" id="spoofMasteryRank" type="number" min="-1" /> </div>
</div> <div class="form-group mt-2">
<button class="btn btn-primary mt-3" type="submit">Save Settings</button> <label class="form-label" for="spoofMasteryRank">
</form> Spoofed Mastery Rank (-1 to disable)
</label>
<input class="form-control" id="spoofMasteryRank" type="number" min="-1" />
</div>
<button class="btn btn-primary mt-3" type="submit">Save Settings</button>
</form>
</div>
</div> </div>
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">

View File

@ -792,7 +792,7 @@ const uiConfigs = [
]; ];
function doChangeSettings() { function doChangeSettings() {
fetch("/custom/config") fetch("/custom/config?" + window.authz)
.then(response => response.json()) .then(response => response.json())
.then(json => { .then(json => {
for (const i of uiConfigs) { for (const i of uiConfigs) {
@ -810,7 +810,7 @@ function doChangeSettings() {
} }
} }
$.post({ $.post({
url: "/custom/config", url: "/custom/config?" + window.authz,
contentType: "text/plain", contentType: "text/plain",
data: JSON.stringify(json, null, 2) data: JSON.stringify(json, null, 2)
}); });
@ -820,23 +820,34 @@ function doChangeSettings() {
// Cheats route // Cheats route
single.getRoute("/webui/cheats").on("beforeload", function () { single.getRoute("/webui/cheats").on("beforeload", function () {
fetch("/custom/config") let interval;
.then(response => response.json()) interval = setInterval(() => {
.then(json => if (window.authz) {
Object.entries(json).forEach(entry => { clearInterval(interval);
const [key, value] = entry; fetch("/custom/config?" + window.authz).then(res => {
var x = document.getElementById(`${key}`); if (res.status == 200) {
if (x != null) { $("#server-settings").removeClass("d-none");
if (x.type == "checkbox") { res.json().then(json =>
if (value === true) { Object.entries(json).forEach(entry => {
x.setAttribute("checked", "checked"); const [key, value] = entry;
} var x = document.getElementById(`${key}`);
} else if (x.type == "number") { if (x != null) {
x.setAttribute("value", `${value}`); if (x.type == "checkbox") {
} if (value === true) {
x.setAttribute("checked", "checked");
}
} else if (x.type == "number") {
x.setAttribute("value", `${value}`);
}
}
})
);
} else {
$("#server-settings-no-perms").removeClass("d-none");
} }
}) });
); }
}, 10);
fetch("http://localhost:61558/ping", { mode: "no-cors" }) fetch("http://localhost:61558/ping", { mode: "no-cors" })
.then(() => { .then(() => {