feat(runtime): 即梦本机运行时 - 接入安全生成闭环与桌面本机渠道
Refs #225 Co-authored-by: zkhyww <127009345+zkhyww@users.noreply.github.com>
This commit is contained in:
64
canvas-agent/src/cli-child-environment.ts
Normal file
64
canvas-agent/src/cli-child-environment.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
const WINDOWS_ENVIRONMENT_KEYS = new Map([
|
||||
"PATH", "PATHEXT", "SYSTEMROOT", "WINDIR", "COMSPEC", "TEMP", "TMP",
|
||||
"USERPROFILE", "HOMEDRIVE", "HOMEPATH", "APPDATA", "LOCALAPPDATA",
|
||||
"PROGRAMFILES", "PROGRAMFILES(X86)", "PROGRAMW6432",
|
||||
"LANG", "LC_ALL", "LC_CTYPE", "TERM", "DISPLAY", "WAYLAND_DISPLAY",
|
||||
"XAUTHORITY", "DBUS_SESSION_BUS_ADDRESS", "HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY",
|
||||
].map((key) => [key, key]));
|
||||
|
||||
const POSIX_ENVIRONMENT_KEYS = new Set([
|
||||
"PATH", "HOME", "XDG_CONFIG_HOME", "XDG_DATA_HOME", "XDG_CACHE_HOME", "TMPDIR",
|
||||
"LANG", "LC_ALL", "LC_CTYPE", "TERM", "DISPLAY", "WAYLAND_DISPLAY",
|
||||
"XAUTHORITY", "DBUS_SESSION_BUS_ADDRESS", "HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY",
|
||||
]);
|
||||
|
||||
export type CliChildEnvironmentErrorReason = "conflict" | "proxy" | "no_proxy";
|
||||
|
||||
export class CliChildEnvironmentError extends Error {
|
||||
readonly code = "cli_environment_invalid";
|
||||
|
||||
constructor(readonly reason: CliChildEnvironmentErrorReason) {
|
||||
super("CLI child environment is invalid");
|
||||
this.name = "CliChildEnvironmentError";
|
||||
}
|
||||
}
|
||||
|
||||
// Only pass OS session and explicitly validated proxy settings to local CLI children.
|
||||
export function buildCliChildEnvironment(source: Record<string, string | undefined>) {
|
||||
const result: Record<string, string> = {};
|
||||
const seen = new Map<string, string>();
|
||||
for (const [rawKey, value] of Object.entries(source)) {
|
||||
if (value === undefined) continue;
|
||||
const key = process.platform === "win32" ? rawKey.toUpperCase() : rawKey;
|
||||
const allowed = process.platform === "win32"
|
||||
? WINDOWS_ENVIRONMENT_KEYS.get(key)
|
||||
: POSIX_ENVIRONMENT_KEYS.has(key) ? key : undefined;
|
||||
if (!allowed) continue;
|
||||
const previous = seen.get(key);
|
||||
if (previous !== undefined && previous !== value) {
|
||||
throw new CliChildEnvironmentError("conflict");
|
||||
}
|
||||
validateProxyValue(allowed, value);
|
||||
seen.set(key, value);
|
||||
result[allowed] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function validateProxyValue(key: string, value: string) {
|
||||
if (key === "HTTP_PROXY" || key === "HTTPS_PROXY") {
|
||||
try {
|
||||
const url = new URL(value);
|
||||
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) throw new Error();
|
||||
} catch {
|
||||
throw new CliChildEnvironmentError("proxy");
|
||||
}
|
||||
}
|
||||
if (key === "NO_PROXY" && value) {
|
||||
const entries = value.split(",").map((entry) => entry.trim());
|
||||
if (entries.some((entry) => !entry
|
||||
|| !/^(?:\.?[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*|\[[0-9A-Fa-f:]+\]|[0-9A-Fa-f:.]+)(?::\d{1,5})?$/.test(entry))) {
|
||||
throw new CliChildEnvironmentError("no_proxy");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user