feat: add server settings (toggle on/off, port selection, start on system start) to Settings UI and backend

This commit is contained in:
Schwitzz
2026-10-30 13:56:23 -05:00
parent 42733b4799
commit fa22a755ee
5 changed files with 454 additions and 4 deletions
+97
View File
@@ -1,4 +1,5 @@
import { createUlid, type AuditLogEntry, type Role, type User } from "@pubscript/core";
import { useSettings } from "./store/settings.js";
const BASE = "/api";
const TOKEN_KEY = "pubscript.admin.token";
@@ -138,6 +139,10 @@ async function bootstrapAdminSession(): Promise<string | null> {
}
async function request<T>(path: string, init?: RequestInit, retried = false): Promise<T> {
const { serverEnabled } = useSettings.getState();
if (!serverEnabled) {
throw new Error("Server disabled in settings (Local Storage Mode)");
}
const token = getStoredToken();
const headers: Record<string, string> = {
...(init?.body ? { "Content-Type": "application/json" } : {}),
@@ -361,4 +366,96 @@ export const api = {
}),
logout: () => request<{ ok: true }>("/auth/logout", { method: "POST" }),
getServerConfig: async (portHint?: number): Promise<{
online: boolean;
enabled: boolean;
port: number;
activePort?: number;
startOnBoot: boolean;
}> => {
const endpoints = [
"/api/system/server-config",
...(portHint ? [`http://localhost:${portHint}/api/system/server-config`] : []),
];
for (const url of endpoints) {
try {
const res = await fetch(url, { credentials: "include" });
const ct = res.headers.get("content-type") ?? "";
if (res.ok && ct.includes("application/json")) {
const data = (await res.json()) as {
enabled: boolean;
port: number;
activePort?: number;
startOnBoot: boolean;
};
return {
online: true,
enabled: data.enabled,
port: data.port,
...(data.activePort !== undefined ? { activePort: data.activePort } : {}),
startOnBoot: data.startOnBoot,
};
}
} catch {
/* try next endpoint */
}
}
return {
online: false,
enabled: true,
port: portHint ?? 8081,
startOnBoot: false,
};
},
updateServerConfig: async (
patch: { enabled?: boolean; port?: number; startOnBoot?: boolean },
portHint?: number,
): Promise<{
online: boolean;
enabled: boolean;
port: number;
activePort?: number;
startOnBoot: boolean;
}> => {
const endpoints = [
"/api/system/server-config",
...(portHint ? [`http://localhost:${portHint}/api/system/server-config`] : []),
];
for (const url of endpoints) {
try {
const res = await fetch(url, {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(patch),
});
const ct = res.headers.get("content-type") ?? "";
if (res.ok && ct.includes("application/json")) {
const data = (await res.json()) as {
enabled: boolean;
port: number;
activePort?: number;
startOnBoot: boolean;
};
return {
online: true,
enabled: data.enabled,
port: data.port,
...(data.activePort !== undefined ? { activePort: data.activePort } : {}),
startOnBoot: data.startOnBoot,
};
}
} catch {
/* try next endpoint */
}
}
return {
online: false,
enabled: patch.enabled ?? true,
port: patch.port ?? portHint ?? 8081,
startOnBoot: patch.startOnBoot ?? false,
};
},
};