@chainingintention/pi-web-cn 1.202606.4 → 1.202606.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/client/assets/{CodeViewer-BNKhIElN.js → CodeViewer-DRxmEzh1.js} +1 -1
  2. package/dist/client/assets/{TerminalPanel-VPiiPQfC.js → TerminalPanel-BcGKwlLZ.js} +1 -1
  3. package/dist/client/assets/{index-Csx3hC75.js → index-BZE2v69K.js} +149 -141
  4. package/dist/client/index.html +1 -1
  5. package/dist/config.js +72 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/server/app.js +48 -17
  8. package/dist/server/app.js.map +1 -1
  9. package/dist/server/configRoutes.js +77 -0
  10. package/dist/server/configRoutes.js.map +1 -1
  11. package/dist/server/gitRoutes.js +16 -3
  12. package/dist/server/gitRoutes.js.map +1 -1
  13. package/dist/server/managementEmbed.js +205 -0
  14. package/dist/server/managementEmbed.js.map +1 -0
  15. package/dist/server/sessiond/sessionProxyRoutes.js +66 -8
  16. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  17. package/dist/server/sessions/managementPermissionSystem.js +94 -0
  18. package/dist/server/sessions/managementPermissionSystem.js.map +1 -0
  19. package/dist/server/sessions/managementSandbox.js +156 -0
  20. package/dist/server/sessions/managementSandbox.js.map +1 -0
  21. package/dist/server/sessions/piSessionService.js +320 -26
  22. package/dist/server/sessions/piSessionService.js.map +1 -1
  23. package/dist/server/sessions/sessionRoutes.js +9 -4
  24. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  25. package/dist/server/terminalProxyRoutes.js +54 -8
  26. package/dist/server/terminalProxyRoutes.js.map +1 -1
  27. package/dist/server/terminals/terminalRoutes.js +12 -3
  28. package/dist/server/terminals/terminalRoutes.js.map +1 -1
  29. package/dist/server/terminals/terminalService.js +48 -4
  30. package/dist/server/terminals/terminalService.js.map +1 -1
  31. package/dist/server/workspaceExplorerRoutes.js +17 -4
  32. package/dist/server/workspaceExplorerRoutes.js.map +1 -1
  33. package/dist/server/workspaces/pathSafety.js +9 -2
  34. package/dist/server/workspaces/pathSafety.js.map +1 -1
  35. package/dist/sessiond/sessionDaemonClient.js +12 -12
  36. package/dist/sessiond/sessionDaemonClient.js.map +1 -1
  37. package/dist/shared/apiTypes.d.ts +18 -0
  38. package/package.json +1 -1
@@ -0,0 +1,205 @@
1
+ import { mkdir, realpath } from "node:fs/promises";
2
+ import { join, relative, resolve, sep, isAbsolute } from "node:path";
3
+ export const MANAGEMENT_EMBED_MODE_HEADER = "x-pi-web-embed-mode";
4
+ export const MANAGEMENT_EMBED_TOKEN_HEADER = "x-pi-web-embed-token";
5
+ export const MANAGEMENT_EMBED_CONTEXT_HEADER = "x-pi-web-management-context";
6
+ const MANAGEMENT_FORCE_DENY_TOOLS = new Set(["bash", "shell", "terminal", "terminal-command-runs"]);
7
+ export function readManagementEmbedRequest(headers, query) {
8
+ const modeHeader = firstHeader(headers[MANAGEMENT_EMBED_MODE_HEADER]);
9
+ const tokenHeader = firstHeader(headers[MANAGEMENT_EMBED_TOKEN_HEADER]);
10
+ const embedQuery = typeof query?.["embed"] === "string" ? query["embed"].trim() : undefined;
11
+ const tokenQuery = typeof query?.["token"] === "string" ? query["token"].trim() : undefined;
12
+ const isManagement = modeHeader === "management" || embedQuery === "management" || tokenHeader !== undefined || tokenQuery !== undefined;
13
+ const token = tokenHeader ?? tokenQuery;
14
+ return {
15
+ ...(isManagement ? { mode: "management" } : {}),
16
+ ...(token === undefined ? {} : { token }),
17
+ };
18
+ }
19
+ export async function managementContextForRequest(request, runtime) {
20
+ const embed = readManagementEmbedRequest(request.headers, isRecord(request.query) ? request.query : undefined);
21
+ if (embed.mode !== "management")
22
+ return undefined;
23
+ if (runtime?.enabled !== true)
24
+ throw new Error("Management embed mode is not configured");
25
+ if (embed.token === undefined || embed.token === "")
26
+ throw new Error("Management embed token is required");
27
+ return runtime.authenticate(embed.token);
28
+ }
29
+ export function createManagementEmbedRuntime(config, env = process.env) {
30
+ if (config?.enabled !== true)
31
+ return undefined;
32
+ const introspectionUrl = config.auth?.introspectionUrl?.trim();
33
+ const configuredServiceSecretEnv = config.auth?.serviceSecretEnv?.trim();
34
+ const serviceSecretEnv = configuredServiceSecretEnv !== undefined && configuredServiceSecretEnv !== "" ? configuredServiceSecretEnv : "PI_WEB_MANAGEMENT_EMBED_SERVICE_TOKEN";
35
+ const serviceSecret = env[serviceSecretEnv]?.trim();
36
+ if (introspectionUrl === undefined || introspectionUrl === "" || serviceSecret === undefined || serviceSecret === "") {
37
+ return {
38
+ enabled: true,
39
+ projectRoot: config.projectRoot ?? "/root/Piweb",
40
+ authenticate: () => Promise.reject(new Error("Management embed auth is not configured")),
41
+ };
42
+ }
43
+ return {
44
+ enabled: true,
45
+ projectRoot: config.projectRoot ?? "/root/Piweb",
46
+ authenticate: async (token) => introspectManagementToken(introspectionUrl, serviceSecret, token),
47
+ };
48
+ }
49
+ export async function managedProjectPath(projectRoot, rootUserId, projectId) {
50
+ const root = await ensureRealDirectory(projectRoot);
51
+ const requested = join(root, safePathSegment(rootUserId), safePathSegment(projectId));
52
+ ensureInside(root, requested);
53
+ await mkdir(requested, { recursive: true });
54
+ const target = await realpath(requested);
55
+ ensureInside(root, target);
56
+ return target;
57
+ }
58
+ export async function projectFromManagedEmbedContext(projectRoot, context, projectId) {
59
+ const entry = context.projects.find((project) => project.id === projectId);
60
+ if (entry === undefined)
61
+ throw new Error("Project is not authorized for this management session");
62
+ const entryRoot = entry.root?.trim();
63
+ const path = entryRoot !== undefined && entryRoot !== ""
64
+ ? await assertManagedCwd(projectRoot, context, entryRoot)
65
+ : await managedProjectPath(projectRoot, context.user.rootUserId, entry.id);
66
+ return { id: entry.id, name: entry.name !== "" ? entry.name : entry.id, path, createdAt: new Date(0).toISOString() };
67
+ }
68
+ export async function projectsFromManagedEmbedContext(projectRoot, context) {
69
+ return Promise.all(context.projects.map((project) => projectFromManagedEmbedContext(projectRoot, context, project.id)));
70
+ }
71
+ export async function assertManagedCwd(projectRoot, context, cwd) {
72
+ const root = await ensureRealDirectory(projectRoot);
73
+ const requested = await realpath(resolve(cwd));
74
+ ensureInside(root, requested);
75
+ const authorizedRoots = await Promise.all(context.projects.map(async (project) => {
76
+ const projectRootOverride = project.root?.trim();
77
+ if (projectRootOverride !== undefined && projectRootOverride !== "")
78
+ return realpath(resolve(projectRootOverride));
79
+ return managedProjectPath(root, context.user.rootUserId, project.id);
80
+ }));
81
+ if (!authorizedRoots.some((authorized) => isInside(authorized, requested))) {
82
+ throw new Error("Path is outside the managed project sandbox");
83
+ }
84
+ return requested;
85
+ }
86
+ export function managementToolAllowed(context, tool) {
87
+ if (MANAGEMENT_FORCE_DENY_TOOLS.has(tool))
88
+ return false;
89
+ const deny = new Set(context.tools?.deny ?? []);
90
+ if (deny.has(tool))
91
+ return false;
92
+ const allow = context.tools?.allow;
93
+ return allow === undefined || allow.length === 0 || allow.includes(tool);
94
+ }
95
+ export function encodeManagementContext(context) {
96
+ return Buffer.from(JSON.stringify(context), "utf8").toString("base64url");
97
+ }
98
+ export function decodeManagementContext(value) {
99
+ if (value === undefined || value === "")
100
+ return undefined;
101
+ const parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
102
+ if (!isRecord(parsed))
103
+ throw new Error("Invalid management embed context");
104
+ return parseIntrospectionPayload({ active: true, ...parsed });
105
+ }
106
+ async function introspectManagementToken(url, serviceSecret, token) {
107
+ const response = await fetch(url, {
108
+ method: "POST",
109
+ headers: { "content-type": "application/json", "x-pi-web-embed-secret": serviceSecret },
110
+ body: JSON.stringify({ token }),
111
+ });
112
+ const payload = await response.json().catch(() => undefined);
113
+ if (!response.ok || !isRecord(payload) || payload["active"] !== true)
114
+ throw new Error("Management embed token is invalid");
115
+ return parseIntrospectionPayload(payload);
116
+ }
117
+ function parseIntrospectionPayload(payload) {
118
+ const user = payload["user"];
119
+ const projects = payload["projects"];
120
+ if (!isRecord(user) || !Array.isArray(projects))
121
+ throw new Error("Management embed introspection response is invalid");
122
+ const context = {
123
+ user: {
124
+ id: stringField(user, "id"),
125
+ rootUserId: stringField(user, "rootUserId"),
126
+ roles: stringArray(user["roles"]),
127
+ permissions: stringArray(user["permissions"]),
128
+ },
129
+ projects: projects.map(parseProjectEntry),
130
+ };
131
+ if (isRecord(payload["tools"]))
132
+ context.tools = parseTools(payload["tools"]);
133
+ if (isRecord(payload["sandbox"]))
134
+ context.sandbox = parseSandbox(payload["sandbox"]);
135
+ if (typeof payload["expiresAt"] === "string")
136
+ context.expiresAt = payload["expiresAt"];
137
+ return context;
138
+ }
139
+ function parseTools(value) {
140
+ return {
141
+ ...(Array.isArray(value["allow"]) ? { allow: stringArray(value["allow"]) } : {}),
142
+ ...(Array.isArray(value["deny"]) ? { deny: stringArray(value["deny"]) } : {}),
143
+ ...(isRecord(value["permissions"]) ? { permissions: booleanRecord(value["permissions"]) } : {}),
144
+ };
145
+ }
146
+ function parseSandbox(value) {
147
+ return {
148
+ ...(typeof value["pythonExecutable"] === "string" ? { pythonExecutable: value["pythonExecutable"] } : {}),
149
+ ...(isRecord(value["env"]) ? { env: stringRecord(value["env"]) } : {}),
150
+ };
151
+ }
152
+ function parseProjectEntry(value) {
153
+ if (!isRecord(value))
154
+ throw new Error("Management embed project entry is invalid");
155
+ return {
156
+ id: stringField(value, "id"),
157
+ name: stringField(value, "name"),
158
+ ...(typeof value["role"] === "string" ? { role: value["role"] } : {}),
159
+ ...(typeof value["root"] === "string" ? { root: value["root"] } : {}),
160
+ };
161
+ }
162
+ async function ensureRealDirectory(path) {
163
+ await mkdir(path, { recursive: true });
164
+ return realpath(path);
165
+ }
166
+ function firstHeader(value) {
167
+ const header = Array.isArray(value) ? value[0] : value;
168
+ const normalized = header?.trim();
169
+ return normalized === "" ? undefined : normalized;
170
+ }
171
+ function safePathSegment(value) {
172
+ const segment = value.trim().replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
173
+ return segment === "" ? "unknown" : segment;
174
+ }
175
+ function ensureInside(root, target) {
176
+ if (!isInside(root, target))
177
+ throw new Error("Path is outside the managed project sandbox");
178
+ }
179
+ function isInside(root, target) {
180
+ const rel = relative(root, target);
181
+ if (rel === "")
182
+ return true;
183
+ if (rel.startsWith("..") || isAbsolute(rel))
184
+ return false;
185
+ return sep === "/" || !rel.split(sep).includes("..");
186
+ }
187
+ function stringField(value, key) {
188
+ const field = value[key];
189
+ if (typeof field !== "string" || field.trim() === "")
190
+ throw new Error(`Management embed ${key} is required`);
191
+ return field.trim();
192
+ }
193
+ function stringArray(value) {
194
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim() !== "").map((item) => item.trim()) : [];
195
+ }
196
+ function stringRecord(value) {
197
+ return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
198
+ }
199
+ function booleanRecord(value) {
200
+ return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "boolean"));
201
+ }
202
+ function isRecord(value) {
203
+ return typeof value === "object" && value !== null && !Array.isArray(value);
204
+ }
205
+ //# sourceMappingURL=managementEmbed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managementEmbed.js","sourceRoot":"","sources":["../../src/server/managementEmbed.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  import { WebSocket } from "ws";
2
2
  import { SessionDaemonClient } from "../../sessiond/sessionDaemonClient.js";
3
- export function registerSessionProxyRoutes(app, daemon = new SessionDaemonClient(), prefix = "/api") {
3
+ import { assertManagedCwd, encodeManagementContext, managementContextForRequest, MANAGEMENT_EMBED_CONTEXT_HEADER } from "../managementEmbed.js";
4
+ export function registerSessionProxyRoutes(app, daemon = new SessionDaemonClient(), prefix = "/api", managementEmbed) {
4
5
  const proxy = async (request, reply) => {
5
6
  try {
6
- const upstream = await daemon.request(request.method, stripPrefix(request.url, prefix), request.body);
7
+ const managementContext = await managementContextForRequest(request, managementEmbed);
8
+ const body = await managementBody(request.url, request.body, managementContext, managementEmbed);
9
+ const upstream = await daemon.request(request.method, stripPrefix(request.url, prefix), body, managementHeaders(managementContext));
7
10
  reply.code(upstream.statusCode);
8
11
  const contentType = upstream.headers["content-type"];
9
12
  if (contentType !== undefined && contentType !== "")
@@ -15,15 +18,40 @@ export function registerSessionProxyRoutes(app, daemon = new SessionDaemonClient
15
18
  return undefined;
16
19
  }
17
20
  };
18
- app.get(`${prefix}/sessiond/health`, (_request, reply) => proxy({ method: "GET", url: `${prefix}/health` }, reply));
21
+ app.get(`${prefix}/sessiond/health`, async (_request, reply) => {
22
+ try {
23
+ const upstream = await daemon.request("GET", "/health");
24
+ reply.code(upstream.statusCode);
25
+ const contentType = upstream.headers["content-type"];
26
+ if (contentType !== undefined && contentType !== "")
27
+ reply.header("content-type", contentType);
28
+ return upstream.body !== "" ? parseJson(upstream.body) : undefined;
29
+ }
30
+ catch (error) {
31
+ requestFailed(reply, error);
32
+ return undefined;
33
+ }
34
+ });
19
35
  app.get(`${prefix}/sessions/:sessionId/events`, { websocket: true }, (socket, request) => {
20
- bridgeSockets(socket, daemon.connectWebSocket(`/sessions/${request.params.sessionId}/events`));
36
+ void managementContextForRequest(request, managementEmbed).then((context) => {
37
+ bridgeSockets(socket, daemon.connectWebSocket(`/sessions/${request.params.sessionId}/events`, managementHeaders(context)));
38
+ }).catch((error) => {
39
+ closeSocketWithError(socket, error);
40
+ });
21
41
  });
22
- app.get(`${prefix}/sessions/events`, { websocket: true }, (socket) => {
23
- bridgeSockets(socket, daemon.connectWebSocket("/sessions/events"));
42
+ app.get(`${prefix}/sessions/events`, { websocket: true }, (socket, request) => {
43
+ void managementContextForRequest(request, managementEmbed).then((context) => {
44
+ bridgeSockets(socket, daemon.connectWebSocket("/sessions/events", managementHeaders(context)));
45
+ }).catch((error) => {
46
+ closeSocketWithError(socket, error);
47
+ });
24
48
  });
25
- app.get(`${prefix}/events`, { websocket: true }, (socket) => {
26
- bridgeSockets(socket, daemon.connectWebSocket("/events"));
49
+ app.get(`${prefix}/events`, { websocket: true }, (socket, request) => {
50
+ void managementContextForRequest(request, managementEmbed).then((context) => {
51
+ bridgeSockets(socket, daemon.connectWebSocket("/events", managementHeaders(context)));
52
+ }).catch((error) => {
53
+ closeSocketWithError(socket, error);
54
+ });
27
55
  });
28
56
  app.all(`${prefix}/activity`, (request, reply) => proxy(request, reply));
29
57
  app.all(`${prefix}/auth`, (request, reply) => proxy(request, reply));
@@ -31,6 +59,29 @@ export function registerSessionProxyRoutes(app, daemon = new SessionDaemonClient
31
59
  app.all(`${prefix}/sessions`, (request, reply) => proxy(request, reply));
32
60
  app.all(`${prefix}/sessions/*`, (request, reply) => proxy(request, reply));
33
61
  }
62
+ async function managementBody(url, body, context, managementEmbed) {
63
+ if (context === undefined)
64
+ return body;
65
+ const path = stripPrefix(url, "");
66
+ if (path.startsWith("/sessions?")) {
67
+ const cwd = new URL(`http://local${path}`).searchParams.get("cwd");
68
+ if (cwd !== null)
69
+ await assertManagedCwd(managementProjectRoot(managementEmbed), context, cwd);
70
+ return body;
71
+ }
72
+ if (path === "/sessions" && isRecord(body) && typeof body["cwd"] === "string") {
73
+ return { ...body, cwd: await assertManagedCwd(managementProjectRoot(managementEmbed), context, body["cwd"]) };
74
+ }
75
+ return body;
76
+ }
77
+ function managementHeaders(context) {
78
+ return context === undefined ? undefined : { [MANAGEMENT_EMBED_CONTEXT_HEADER]: encodeManagementContext(context) };
79
+ }
80
+ function managementProjectRoot(managementEmbed) {
81
+ if (managementEmbed === undefined)
82
+ throw new Error("Management embed mode is not configured");
83
+ return managementEmbed.projectRoot;
84
+ }
34
85
  function stripPrefix(url, prefix) {
35
86
  const path = url.split("?", 1)[0] ?? url;
36
87
  const query = url.slice(path.length);
@@ -57,4 +108,11 @@ function sendIfOpen(socket, data) {
57
108
  socket.send(data);
58
109
  }
59
110
  }
111
+ function closeSocketWithError(socket, error) {
112
+ socket.send(JSON.stringify({ type: "error", message: error instanceof Error ? error.message : String(error) }));
113
+ socket.close();
114
+ }
115
+ function isRecord(value) {
116
+ return typeof value === "object" && value !== null && !Array.isArray(value);
117
+ }
60
118
  //# sourceMappingURL=sessionProxyRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessionProxyRoutes.js","sourceRoot":"","sources":["../../../src/server/sessiond/sessionProxyRoutes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessionProxyRoutes.js","sourceRoot":"","sources":["../../../src/server/sessiond/sessionProxyRoutes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import { createHash } from "node:crypto";
2
+ import { mkdir, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ export const PI_PERMISSION_SYSTEM_POLICY_AGENT_DIR = "PI_PERMISSION_SYSTEM_POLICY_AGENT_DIR";
5
+ const MANAGEMENT_AGENT_TOOL_NAMES = ["read", "write", "edit", "ls", "grep", "find", "python"];
6
+ export function createManagementPermissionSystemPolicy(context) {
7
+ const tools = {
8
+ "*": "deny",
9
+ };
10
+ for (const tool of managementAgentToolNames(context))
11
+ tools[tool] = "allow";
12
+ for (const tool of managementDeniedToolNames(context))
13
+ tools[tool] = "deny";
14
+ return {
15
+ defaultPolicy: {
16
+ tools: "deny",
17
+ bash: "deny",
18
+ mcp: "deny",
19
+ skills: "deny",
20
+ special: "deny",
21
+ },
22
+ tools,
23
+ bash: { "*": "deny" },
24
+ mcp: { "*": "deny" },
25
+ skills: { "*": "deny" },
26
+ special: {
27
+ doom_loop: "deny",
28
+ external_directory: "deny",
29
+ },
30
+ };
31
+ }
32
+ export function managementAgentToolNames(context) {
33
+ const deny = new Set([...(context.tools?.deny ?? []), "bash", "shell", "terminal"]);
34
+ const allow = context.tools?.allow;
35
+ const safeTools = MANAGEMENT_AGENT_TOOL_NAMES.filter((tool) => !deny.has(tool));
36
+ if (allow === undefined || allow.length === 0)
37
+ return [...safeTools];
38
+ return safeTools.filter((tool) => allow.includes(tool));
39
+ }
40
+ export async function writeManagementPermissionSystemPolicy(agentDir, cwd, context) {
41
+ const policyAgentDir = join(agentDir, "management-embed", "permission-system", safePathSegment(context.user.rootUserId), createHash("sha256").update(cwd).digest("hex").slice(0, 16));
42
+ await mkdir(policyAgentDir, { recursive: true });
43
+ await writeFile(join(policyAgentDir, "pi-permissions.jsonc"), `${JSON.stringify(createManagementPermissionSystemPolicy(context), null, 2)}\n`, "utf8");
44
+ return policyAgentDir;
45
+ }
46
+ let runtimeEnvironmentQueue = Promise.resolve();
47
+ export async function withRuntimeCreationEnvironment(env, action) {
48
+ const previousQueue = runtimeEnvironmentQueue;
49
+ let releaseQueue = () => undefined;
50
+ runtimeEnvironmentQueue = new Promise((resolve) => {
51
+ releaseQueue = resolve;
52
+ });
53
+ await previousQueue;
54
+ const previousValues = new Map();
55
+ for (const [key, value] of Object.entries(env)) {
56
+ previousValues.set(key, process.env[key]);
57
+ if (value === undefined)
58
+ Reflect.deleteProperty(process.env, key);
59
+ else
60
+ process.env[key] = value;
61
+ }
62
+ try {
63
+ return await action();
64
+ }
65
+ finally {
66
+ for (const [key, value] of previousValues) {
67
+ if (value === undefined)
68
+ Reflect.deleteProperty(process.env, key);
69
+ else
70
+ process.env[key] = value;
71
+ }
72
+ releaseQueue();
73
+ }
74
+ }
75
+ function managementDeniedToolNames(context) {
76
+ return [
77
+ "bash",
78
+ "shell",
79
+ "terminal",
80
+ "terminal-command-runs",
81
+ "powershell",
82
+ "pwsh",
83
+ "mcp",
84
+ "http",
85
+ "webfetch",
86
+ "websearch",
87
+ ...(context.tools?.deny ?? []),
88
+ ];
89
+ }
90
+ function safePathSegment(value) {
91
+ const safe = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
92
+ return safe === "" ? "user" : safe.slice(0, 80);
93
+ }
94
+ //# sourceMappingURL=managementPermissionSystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managementPermissionSystem.js","sourceRoot":"","sources":["../../../src/server/sessions/managementPermissionSystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ const DEFAULT_PATH = "/usr/local/bin:/usr/bin:/bin";
2
+ const SAFE_HOST_ENV_KEYS = ["PATH", "LANG", "LC_ALL", "LC_CTYPE"];
3
+ const SENSITIVE_ENV_PATTERNS = ["TOKEN", "SECRET", "PASSWORD", "PRIVATE_KEY", "API_KEY"];
4
+ const SANDBOX_WORKSPACE = "/workspace";
5
+ const SANDBOX_HOME = "/tmp/pi-web-home";
6
+ export const DEFAULT_BUBBLEWRAP_PATHS = [
7
+ "/usr",
8
+ "/bin",
9
+ "/lib",
10
+ "/lib64",
11
+ "/etc/alternatives",
12
+ "/etc/ld.so.cache",
13
+ "/etc/ssl",
14
+ "/etc/ca-certificates",
15
+ ];
16
+ export function createManagedSandboxEnvironment(options) {
17
+ const env = {};
18
+ for (const key of SAFE_HOST_ENV_KEYS) {
19
+ const value = options.hostEnv[key];
20
+ if (value !== undefined && value !== "")
21
+ env[key] = value;
22
+ }
23
+ env["PATH"] ??= DEFAULT_PATH;
24
+ for (const [key, value] of Object.entries(options.context.sandbox?.env ?? {})) {
25
+ assertNonSensitiveSandboxEnvKey(key);
26
+ env[key] = value;
27
+ }
28
+ env["HOME"] = SANDBOX_HOME;
29
+ env["TMPDIR"] = "/tmp";
30
+ return env;
31
+ }
32
+ export function createBubblewrapPythonInvocation(options) {
33
+ const args = [
34
+ "--unshare-net",
35
+ "--unshare-ipc",
36
+ "--unshare-pid",
37
+ "--die-with-parent",
38
+ "--clearenv",
39
+ ...Object.entries(options.env ?? {}).flatMap(([key, value]) => ["--setenv", key, value ?? ""]),
40
+ "--tmpfs",
41
+ "/tmp",
42
+ "--dir",
43
+ SANDBOX_HOME,
44
+ "--proc",
45
+ "/proc",
46
+ "--dev",
47
+ "/dev",
48
+ ...[...new Set(options.readOnlyPaths ?? DEFAULT_BUBBLEWRAP_PATHS)].flatMap((path) => ["--ro-bind", path, path]),
49
+ "--bind",
50
+ options.workspaceRoot,
51
+ SANDBOX_WORKSPACE,
52
+ "--chdir",
53
+ SANDBOX_WORKSPACE,
54
+ options.pythonExecutable,
55
+ "-I",
56
+ "-",
57
+ ];
58
+ return { command: options.bubblewrapExecutable, args };
59
+ }
60
+ export function bubblewrapUnavailableReason(output) {
61
+ if (output.includes("setting up uid map: Permission denied"))
62
+ return "setting up uid map: Permission denied";
63
+ if (output.includes("Failed RTM_NEWADDR: Operation not permitted"))
64
+ return "Failed RTM_NEWADDR: Operation not permitted";
65
+ if (output.includes("No permissions to creating new namespace"))
66
+ return "No permissions to creating new namespace";
67
+ if (output.includes("Creating new namespace failed"))
68
+ return "Creating new namespace failed";
69
+ return undefined;
70
+ }
71
+ export function createManagedPythonFallbackPrelude(root) {
72
+ return `
73
+ import builtins
74
+ import io
75
+ import os
76
+ import pathlib
77
+ import subprocess
78
+
79
+ _PI_WEB_ROOT = ${JSON.stringify(root)}
80
+ _PI_WEB_OPEN = builtins.open
81
+ _PI_WEB_IO_OPEN = io.open
82
+ _PI_WEB_PATH_OPEN = pathlib.Path.open
83
+ _PI_WEB_PATH_READ_TEXT = pathlib.Path.read_text
84
+ _PI_WEB_PATH_READ_BYTES = pathlib.Path.read_bytes
85
+ _PI_WEB_PATH_WRITE_TEXT = pathlib.Path.write_text
86
+ _PI_WEB_PATH_WRITE_BYTES = pathlib.Path.write_bytes
87
+
88
+ def _pi_web_inside(path):
89
+ real = os.path.realpath(os.fspath(path))
90
+ rel = os.path.relpath(real, _PI_WEB_ROOT)
91
+ return rel == "." or (not rel.startswith("..") and not os.path.isabs(rel))
92
+
93
+ def _pi_web_check_path(path):
94
+ if not isinstance(path, (str, bytes, os.PathLike)):
95
+ return
96
+ if not _pi_web_inside(path):
97
+ raise PermissionError("path outside the managed project sandbox: %s" % path)
98
+
99
+ def open(file, mode="r", *args, **kwargs):
100
+ _pi_web_check_path(file)
101
+ return _PI_WEB_OPEN(file, mode, *args, **kwargs)
102
+
103
+ def _pi_web_path_open(self, *args, **kwargs):
104
+ _pi_web_check_path(self)
105
+ return _PI_WEB_PATH_OPEN(self, *args, **kwargs)
106
+
107
+ def _pi_web_path_read_text(self, *args, **kwargs):
108
+ _pi_web_check_path(self)
109
+ return _PI_WEB_PATH_READ_TEXT(self, *args, **kwargs)
110
+
111
+ def _pi_web_path_read_bytes(self, *args, **kwargs):
112
+ _pi_web_check_path(self)
113
+ return _PI_WEB_PATH_READ_BYTES(self, *args, **kwargs)
114
+
115
+ def _pi_web_path_write_text(self, *args, **kwargs):
116
+ _pi_web_check_path(self)
117
+ return _PI_WEB_PATH_WRITE_TEXT(self, *args, **kwargs)
118
+
119
+ def _pi_web_path_write_bytes(self, *args, **kwargs):
120
+ _pi_web_check_path(self)
121
+ return _PI_WEB_PATH_WRITE_BYTES(self, *args, **kwargs)
122
+
123
+ def _pi_web_blocked_os_path(path, *args, **kwargs):
124
+ _pi_web_check_path(path)
125
+ raise PermissionError("low-level os path APIs are disabled in managed Python fallback mode")
126
+
127
+ def _pi_web_blocked_process(*args, **kwargs):
128
+ raise PermissionError("subprocess and shell execution are disabled in managed Python fallback mode")
129
+
130
+ builtins.open = open
131
+ io.open = open
132
+ pathlib.Path.open = _pi_web_path_open
133
+ pathlib.Path.read_text = _pi_web_path_read_text
134
+ pathlib.Path.read_bytes = _pi_web_path_read_bytes
135
+ pathlib.Path.write_text = _pi_web_path_write_text
136
+ pathlib.Path.write_bytes = _pi_web_path_write_bytes
137
+ os.open = _pi_web_blocked_os_path
138
+ os.listdir = _pi_web_blocked_os_path
139
+ os.scandir = _pi_web_blocked_os_path
140
+ os.stat = _pi_web_blocked_os_path
141
+ os.lstat = _pi_web_blocked_os_path
142
+ subprocess.Popen = _pi_web_blocked_process
143
+ subprocess.run = _pi_web_blocked_process
144
+ subprocess.call = _pi_web_blocked_process
145
+ subprocess.check_call = _pi_web_blocked_process
146
+ subprocess.check_output = _pi_web_blocked_process
147
+ os.system = _pi_web_blocked_process
148
+ `;
149
+ }
150
+ function assertNonSensitiveSandboxEnvKey(key) {
151
+ const upper = key.toUpperCase();
152
+ if (SENSITIVE_ENV_PATTERNS.some((pattern) => upper.includes(pattern))) {
153
+ throw new Error(`Sensitive sandbox environment variable is not allowed: ${key}`);
154
+ }
155
+ }
156
+ //# sourceMappingURL=managementSandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managementSandbox.js","sourceRoot":"","sources":["../../../src/server/sessions/managementSandbox.ts"],"names":[],"mappings":"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"}