feat: add server settings (toggle on/off, port selection, start on system start) to Settings UI and backend
This commit is contained in:
@@ -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,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user