feat: initialize VitePress CMS

This commit is contained in:
Coldsmile_7
2026-06-05 23:21:41 +08:00
commit 928f742d5e
45 changed files with 8214 additions and 0 deletions

70
server/settings.mjs Normal file
View File

@@ -0,0 +1,70 @@
import { db, setSetting } from "./db.mjs";
import { requireCmsUser } from "./auth.mjs";
import { json, readBody } from "./http.mjs";
function requireAdmin(request, response) {
const user = requireCmsUser(request, response);
if (!user) return undefined;
if (user.role !== "system_admin") {
json(response, 403, { error: "System admin permission is required" });
return undefined;
}
return user;
}
function publicSetting(row) {
return {
key: row.key,
value: row.encrypted ? "" : row.value,
encrypted: Boolean(row.encrypted),
updatedAt: row.updated_at,
};
}
async function handleGetSettings(request, response) {
if (!requireAdmin(request, response)) return;
const rows = db
.prepare("SELECT key, value, encrypted, updated_at FROM system_settings ORDER BY key")
.all();
json(response, 200, { settings: rows.map(publicSetting) });
}
async function handleSaveSettings(request, response) {
if (!requireAdmin(request, response)) return;
const body = JSON.parse(await readBody(request) || "{}");
const settings = Array.isArray(body.settings) ? body.settings : [];
settings.forEach((setting) => {
if (!setting.key) return;
setSetting(String(setting.key), String(setting.value ?? ""), Boolean(setting.encrypted));
});
json(response, 200, { ok: true });
}
export async function handleSettingsApi(request, response, url) {
try {
if (url.pathname === "/api/admin/settings" && request.method === "GET") {
await handleGetSettings(request, response);
return true;
}
if (url.pathname === "/api/admin/settings" && request.method === "PUT") {
await handleSaveSettings(request, response);
return true;
}
return false;
} catch (error) {
json(response, 500, {
error: error instanceof Error ? error.message : "Unknown settings API error",
});
return true;
}
}