xxx
This commit is contained in:
parent
9ad61eef3b
commit
789ff22263
44
server.ts
44
server.ts
@ -23,11 +23,6 @@ function loadEnv() {
|
||||
const ENV = loadEnv();
|
||||
|
||||
// 运行时可变配置(可通过 /api/settings 修改并持久化)
|
||||
function parseList(v: string | undefined): string[] {
|
||||
return (v || "").split(",").map((s) => s.trim()).filter(Boolean);
|
||||
}
|
||||
const DEFAULT_WHITELIST = ["d:\\"];
|
||||
|
||||
const config = {
|
||||
BASE_URL: process.env.BASE_URL || ENV.BASE_URL || "https://ark.cn-beijing.volces.com/api/coding/v3",
|
||||
API_KEY: process.env.API_KEY || ENV.API_KEY || "",
|
||||
@ -37,14 +32,12 @@ const config = {
|
||||
PORT: parseInt(process.env.PORT || ENV.PORT || "3000", 10),
|
||||
LOG_LEVEL: (process.env.LOG_LEVEL || ENV.LOG_LEVEL || "debug").toLowerCase(),
|
||||
TEMPERATURE: parseFloat(process.env.TEMPERATURE || ENV.TEMPERATURE || "0.3"),
|
||||
WHITELIST: parseList(process.env.WHITELIST || ENV.WHITELIST).length ? parseList(process.env.WHITELIST || ENV.WHITELIST) : DEFAULT_WHITELIST,
|
||||
BLACKLIST: parseList(process.env.BLACKLIST || ENV.BLACKLIST),
|
||||
DUCKDB_EXE: process.env.DUCKDB_EXE || ENV.DUCKDB_EXE || resolve("bin", "duckdb.exe"),
|
||||
DUCKDB_FILE: process.env.DUCKDB_FILE || ENV.DUCKDB_FILE || resolve("data", "duck.db"),
|
||||
};
|
||||
|
||||
// 持久化配置到 .env(WORKSPACE 为内部默认值,不在设置页暴露)
|
||||
const ENV_KEYS = ["BASE_URL", "API_KEY", "MODEL", "WORKSPACE", "CMD_APPROVE_LEVEL", "PORT", "LOG_LEVEL", "TEMPERATURE", "WHITELIST", "BLACKLIST", "DUCKDB_EXE", "DUCKDB_FILE"] as const;
|
||||
const ENV_KEYS = ["BASE_URL", "API_KEY", "MODEL", "WORKSPACE", "CMD_APPROVE_LEVEL", "PORT", "LOG_LEVEL", "TEMPERATURE", "DUCKDB_EXE", "DUCKDB_FILE"] as const;
|
||||
function saveEnv() {
|
||||
const lines = ENV_KEYS.map((k) => `${k}=${String((config as any)[k])}`);
|
||||
const header = "# Mini AI Assistant 配置(可由设置页面修改)\n";
|
||||
@ -95,26 +88,9 @@ import { resolve, normalize, extname, sep, dirname } from "path";
|
||||
import { read as xlsxRead, write as xlsxWrite, utils } from "xlsx";
|
||||
import { spawn } from "child_process";
|
||||
|
||||
// ---------- 路径安全(白名单 + 黑名单,黑名单优先) ----------
|
||||
// 判断 target 是否等于 base 或位于 base 的子目录下(跨平台)
|
||||
function isWithin(base: string, target: string): boolean {
|
||||
const b = normalize(base).replace(/\\/g, "/").replace(/\/+$/, "");
|
||||
const t = normalize(target).replace(/\\/g, "/").replace(/\/+$/, "");
|
||||
return t === b || t.startsWith(b + "/");
|
||||
}
|
||||
|
||||
// 白名单:允许访问的根目录(默认包含 D 盘根目录);工作区始终隐式允许
|
||||
// 黑名单:禁止访问(优先于白名单);命中黑名单或其子目录则拒绝
|
||||
function isAllowedPath(p: string): boolean {
|
||||
const abs = resolve(config.WORKSPACE, normalize(p));
|
||||
for (const b of config.BLACKLIST) {
|
||||
if (isWithin(b, abs)) return false;
|
||||
}
|
||||
const allowed = [...config.WHITELIST, config.WORKSPACE];
|
||||
for (const w of allowed) {
|
||||
if (isWithin(w, abs)) return true;
|
||||
}
|
||||
return false;
|
||||
// ---------- 路径访问(已移除目录权限限制,全部放行) ----------
|
||||
function isAllowedPath(_p: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------- 危险命令检测 ----------
|
||||
@ -646,8 +622,6 @@ const server = createServer(async (req, res) => {
|
||||
CMD_APPROVE_LEVEL: config.CMD_APPROVE_LEVEL,
|
||||
LOG_LEVEL: config.LOG_LEVEL,
|
||||
TEMPERATURE: config.TEMPERATURE,
|
||||
WHITELIST: config.WHITELIST,
|
||||
BLACKLIST: config.BLACKLIST,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
@ -666,16 +640,8 @@ const server = createServer(async (req, res) => {
|
||||
}
|
||||
if (typeof payload.LOG_LEVEL === "string") config.LOG_LEVEL = payload.LOG_LEVEL.toLowerCase();
|
||||
if (typeof payload.TEMPERATURE === "number") config.TEMPERATURE = payload.TEMPERATURE;
|
||||
if (payload.WHITELIST !== undefined) {
|
||||
const wl = Array.isArray(payload.WHITELIST) ? payload.WHITELIST : String(payload.WHITELIST).split(",");
|
||||
config.WHITELIST = wl.map((s: string) => String(s).trim()).filter(Boolean);
|
||||
}
|
||||
if (payload.BLACKLIST !== undefined) {
|
||||
const bl = Array.isArray(payload.BLACKLIST) ? payload.BLACKLIST : String(payload.BLACKLIST).split(",");
|
||||
config.BLACKLIST = bl.map((s: string) => String(s).trim()).filter(Boolean);
|
||||
}
|
||||
saveEnv();
|
||||
log("info", "settings_updated", { CMD_APPROVE_LEVEL: config.CMD_APPROVE_LEVEL, MODEL: config.MODEL, LOG_LEVEL: config.LOG_LEVEL, WHITELIST: config.WHITELIST, BLACKLIST: config.BLACKLIST });
|
||||
log("info", "settings_updated", { CMD_APPROVE_LEVEL: config.CMD_APPROVE_LEVEL, MODEL: config.MODEL, LOG_LEVEL: config.LOG_LEVEL });
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ ok: true }));
|
||||
return;
|
||||
|
||||
@ -63,19 +63,6 @@
|
||||
</label>
|
||||
<p class="hint">控制执行 Shell 命令时是否需要你审批。</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h4>路径权限(可配置多个)</h4>
|
||||
<label class="row">
|
||||
<span>白名单</span>
|
||||
<input v-model="form.WHITELIST" placeholder="多个目录用逗号分隔,如 d:\ , c:\tmp" />
|
||||
</label>
|
||||
<label class="row">
|
||||
<span>黑名单</span>
|
||||
<input v-model="form.BLACKLIST" placeholder="多个目录用逗号分隔,优先于白名单" />
|
||||
</label>
|
||||
<p class="hint">白名单内的目录(及其子目录)允许访问;黑名单优先,命中即拒绝。默认白名单含 <code>d:\</code>。</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
@ -99,8 +86,6 @@ const form = reactive({
|
||||
CMD_APPROVE_LEVEL: "medium",
|
||||
LOG_LEVEL: "debug",
|
||||
TEMPERATURE: 0.3,
|
||||
WHITELIST: "",
|
||||
BLACKLIST: "",
|
||||
});
|
||||
const saving = ref(false);
|
||||
const msg = ref("");
|
||||
@ -141,8 +126,6 @@ onMounted(async () => {
|
||||
form.CMD_APPROVE_LEVEL = d.CMD_APPROVE_LEVEL || "medium";
|
||||
form.LOG_LEVEL = d.LOG_LEVEL || "debug";
|
||||
form.TEMPERATURE = typeof d.TEMPERATURE === "number" ? d.TEMPERATURE : 0.3;
|
||||
form.WHITELIST = Array.isArray(d.WHITELIST) ? d.WHITELIST.join(", ") : (d.WHITELIST || "d:\\");
|
||||
form.BLACKLIST = Array.isArray(d.BLACKLIST) ? d.BLACKLIST.join(", ") : (d.BLACKLIST || "");
|
||||
// API_KEY 返回脱敏值,不回填明文
|
||||
} catch {
|
||||
msg.value = "加载设置失败";
|
||||
@ -164,8 +147,6 @@ async function save() {
|
||||
CMD_APPROVE_LEVEL: form.CMD_APPROVE_LEVEL,
|
||||
LOG_LEVEL: form.LOG_LEVEL,
|
||||
TEMPERATURE: form.TEMPERATURE,
|
||||
WHITELIST: form.WHITELIST,
|
||||
BLACKLIST: form.BLACKLIST,
|
||||
}),
|
||||
});
|
||||
const d = await r.json();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user