功能:完善用户与项目管理框架
This commit is contained in:
+77
-11
@@ -1,18 +1,64 @@
|
||||
import net from "node:net";
|
||||
import tls from "node:tls";
|
||||
import { db, setSetting } from "./db.mjs";
|
||||
import { requireCmsUser } from "./auth.mjs";
|
||||
import { requirePermission } from "./auth.mjs";
|
||||
import { json, readBody } from "./http.mjs";
|
||||
import { permissions } from "./permissions.mjs";
|
||||
|
||||
function requireAdmin(request, response) {
|
||||
const user = requireCmsUser(request, response);
|
||||
function getSettingValue(key, fallback = "") {
|
||||
return db.prepare("SELECT value FROM system_settings WHERE key = ?").get(key)?.value ?? fallback;
|
||||
}
|
||||
|
||||
if (!user) return undefined;
|
||||
function testSmtpConnection({ host, port }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const socketFactory = Number(port) === 465 ? tls.connect : net.connect;
|
||||
const socket = socketFactory({
|
||||
host,
|
||||
port: Number(port),
|
||||
servername: host,
|
||||
timeout: 10000,
|
||||
});
|
||||
let buffer = "";
|
||||
|
||||
if (user.role !== "system_admin") {
|
||||
json(response, 403, { error: "System admin permission is required" });
|
||||
return undefined;
|
||||
}
|
||||
const finish = (result) => {
|
||||
socket.removeAllListeners();
|
||||
socket.end();
|
||||
resolve(result);
|
||||
};
|
||||
|
||||
return user;
|
||||
socket.on("connect", () => {
|
||||
if (Number(port) === 465) {
|
||||
socket.write("EHLO vitepress-cms.local\r\n");
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("secureConnect", () => {
|
||||
socket.write("EHLO vitepress-cms.local\r\n");
|
||||
});
|
||||
|
||||
socket.on("data", (chunk) => {
|
||||
buffer += chunk.toString("utf-8");
|
||||
|
||||
if (buffer.startsWith("220")) {
|
||||
socket.write("EHLO vitepress-cms.local\r\n");
|
||||
}
|
||||
|
||||
if (buffer.includes("\n250 ") || buffer.includes("\n250-") || buffer.startsWith("250")) {
|
||||
socket.write("QUIT\r\n");
|
||||
finish({
|
||||
ok: true,
|
||||
greeting: buffer.split(/\r?\n/).filter(Boolean).slice(0, 3).join(" / "),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("timeout", () => {
|
||||
socket.destroy();
|
||||
reject(new Error("SMTP connection timed out"));
|
||||
});
|
||||
|
||||
socket.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
function publicSetting(row) {
|
||||
@@ -25,7 +71,7 @@ function publicSetting(row) {
|
||||
}
|
||||
|
||||
async function handleGetSettings(request, response) {
|
||||
if (!requireAdmin(request, response)) return;
|
||||
if (!requirePermission(request, response, permissions.settingsManage)) return;
|
||||
|
||||
const rows = db
|
||||
.prepare("SELECT key, value, encrypted, updated_at FROM system_settings ORDER BY key")
|
||||
@@ -35,7 +81,7 @@ async function handleGetSettings(request, response) {
|
||||
}
|
||||
|
||||
async function handleSaveSettings(request, response) {
|
||||
if (!requireAdmin(request, response)) return;
|
||||
if (!requirePermission(request, response, permissions.settingsManage)) return;
|
||||
|
||||
const body = JSON.parse(await readBody(request) || "{}");
|
||||
const settings = Array.isArray(body.settings) ? body.settings : [];
|
||||
@@ -52,6 +98,21 @@ async function handleSaveSettings(request, response) {
|
||||
json(response, 200, { ok: true });
|
||||
}
|
||||
|
||||
async function handleTestSmtp(request, response) {
|
||||
if (!requirePermission(request, response, permissions.settingsManage)) return;
|
||||
|
||||
const host = getSettingValue("smtp.host");
|
||||
const port = getSettingValue("smtp.port", "587");
|
||||
|
||||
if (!host) {
|
||||
json(response, 400, { error: "SMTP host is required" });
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await testSmtpConnection({ host, port });
|
||||
json(response, 200, result);
|
||||
}
|
||||
|
||||
export async function handleSettingsApi(request, response, url) {
|
||||
try {
|
||||
if (url.pathname === "/api/admin/settings" && request.method === "GET") {
|
||||
@@ -64,6 +125,11 @@ export async function handleSettingsApi(request, response, url) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (url.pathname === "/api/admin/settings/test-smtp" && request.method === "POST") {
|
||||
await handleTestSmtp(request, response);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
json(response, 500, {
|
||||
|
||||
Reference in New Issue
Block a user