jishushell 0.4.30 → 0.5.15

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 (182) hide show
  1. package/apps/anythingllm-container.yaml +287 -0
  2. package/apps/browserless-chromium-container.yaml +18 -6
  3. package/apps/filebrowser-container.yaml +163 -0
  4. package/apps/openclaw-binary.yaml +8 -0
  5. package/apps/openclaw-container.yaml +9 -1
  6. package/apps/openclaw-with-searxng-container.yaml +4 -0
  7. package/apps/searxng-container.yaml +5 -4
  8. package/apps/weknora-container.yaml +471 -0
  9. package/dist/cli/panel.js.map +1 -1
  10. package/dist/config.d.ts +19 -0
  11. package/dist/config.js +99 -1
  12. package/dist/config.js.map +1 -1
  13. package/dist/install.js +3 -3
  14. package/dist/install.js.map +1 -1
  15. package/dist/routes/auth.js +2 -2
  16. package/dist/routes/auth.js.map +1 -1
  17. package/dist/routes/backup.js +64 -11
  18. package/dist/routes/backup.js.map +1 -1
  19. package/dist/routes/external-mounts.d.ts +17 -0
  20. package/dist/routes/external-mounts.js +73 -0
  21. package/dist/routes/external-mounts.js.map +1 -0
  22. package/dist/routes/file-mounts.d.ts +13 -0
  23. package/dist/routes/file-mounts.js +90 -0
  24. package/dist/routes/file-mounts.js.map +1 -0
  25. package/dist/routes/files-organize.d.ts +28 -0
  26. package/dist/routes/files-organize.js +167 -0
  27. package/dist/routes/files-organize.js.map +1 -0
  28. package/dist/routes/files.d.ts +31 -0
  29. package/dist/routes/files.js +321 -0
  30. package/dist/routes/files.js.map +1 -0
  31. package/dist/routes/instances.js +45 -7
  32. package/dist/routes/instances.js.map +1 -1
  33. package/dist/routes/internal.d.ts +2 -0
  34. package/dist/routes/internal.js +59 -0
  35. package/dist/routes/internal.js.map +1 -0
  36. package/dist/routes/setup.js +9 -9
  37. package/dist/routes/setup.js.map +1 -1
  38. package/dist/routes/system.js +1 -1
  39. package/dist/routes/system.js.map +1 -1
  40. package/dist/routes/webdav.d.ts +17 -0
  41. package/dist/routes/webdav.js +114 -0
  42. package/dist/routes/webdav.js.map +1 -0
  43. package/dist/server.js +341 -3
  44. package/dist/server.js.map +1 -1
  45. package/dist/services/app/app-compiler.d.ts +1 -1
  46. package/dist/services/app/app-compiler.js +5 -5
  47. package/dist/services/app/app-compiler.js.map +1 -1
  48. package/dist/services/app/app-manager.d.ts +1 -0
  49. package/dist/services/app/app-manager.js +172 -41
  50. package/dist/services/app/app-manager.js.map +1 -1
  51. package/dist/services/app/custom-manager.js.map +1 -1
  52. package/dist/services/app/hermes-agent-manager.js +1 -0
  53. package/dist/services/app/hermes-agent-manager.js.map +1 -1
  54. package/dist/services/app/ollama-manager.js +1 -1
  55. package/dist/services/app/ollama-manager.js.map +1 -1
  56. package/dist/services/app/openclaw-manager.js +20 -3
  57. package/dist/services/app/openclaw-manager.js.map +1 -1
  58. package/dist/services/app/platform-transform.d.ts +32 -0
  59. package/dist/services/app/platform-transform.js +65 -0
  60. package/dist/services/app/platform-transform.js.map +1 -0
  61. package/dist/services/app-passwords.d.ts +61 -0
  62. package/dist/services/app-passwords.js +173 -0
  63. package/dist/services/app-passwords.js.map +1 -0
  64. package/dist/services/backup-manager.d.ts +11 -0
  65. package/dist/services/backup-manager.js +177 -4
  66. package/dist/services/backup-manager.js.map +1 -1
  67. package/dist/services/connection-apply.d.ts +2 -0
  68. package/dist/services/connection-apply.js +55 -1
  69. package/dist/services/connection-apply.js.map +1 -1
  70. package/dist/services/connection-resolver.js +1 -1
  71. package/dist/services/connection-resolver.js.map +1 -1
  72. package/dist/services/connection-transactor.d.ts +2 -0
  73. package/dist/services/connection-transactor.js +12 -2
  74. package/dist/services/connection-transactor.js.map +1 -1
  75. package/dist/services/external-mounts.d.ts +40 -0
  76. package/dist/services/external-mounts.js +187 -0
  77. package/dist/services/external-mounts.js.map +1 -0
  78. package/dist/services/files-manager.d.ts +252 -0
  79. package/dist/services/files-manager.js +1075 -0
  80. package/dist/services/files-manager.js.map +1 -0
  81. package/dist/services/files-mounts.d.ts +42 -0
  82. package/dist/services/files-mounts.js +207 -0
  83. package/dist/services/files-mounts.js.map +1 -0
  84. package/dist/services/instance-manager.js +1 -23
  85. package/dist/services/instance-manager.js.map +1 -1
  86. package/dist/services/llm-proxy/index.js.map +1 -1
  87. package/dist/services/llm-proxy/ssrf.js +6 -2
  88. package/dist/services/llm-proxy/ssrf.js.map +1 -1
  89. package/dist/services/nomad-manager.d.ts +4 -0
  90. package/dist/services/nomad-manager.js +53 -19
  91. package/dist/services/nomad-manager.js.map +1 -1
  92. package/dist/services/organize/applier.d.ts +46 -0
  93. package/dist/services/organize/applier.js +218 -0
  94. package/dist/services/organize/applier.js.map +1 -0
  95. package/dist/services/organize/rules.d.ts +57 -0
  96. package/dist/services/organize/rules.js +286 -0
  97. package/dist/services/organize/rules.js.map +1 -0
  98. package/dist/services/organize/scanner.d.ts +50 -0
  99. package/dist/services/organize/scanner.js +366 -0
  100. package/dist/services/organize/scanner.js.map +1 -0
  101. package/dist/services/organize/store.d.ts +14 -0
  102. package/dist/services/organize/store.js +82 -0
  103. package/dist/services/organize/store.js.map +1 -0
  104. package/dist/services/panel-manager.js +20 -1
  105. package/dist/services/panel-manager.js.map +1 -1
  106. package/dist/services/process-manager.js +3 -2
  107. package/dist/services/process-manager.js.map +1 -1
  108. package/dist/services/runtime/adapters/hermes.js +1 -1
  109. package/dist/services/runtime/adapters/hermes.js.map +1 -1
  110. package/dist/services/runtime/adapters/openclaw-routes.d.ts +8 -2
  111. package/dist/services/runtime/adapters/openclaw-routes.js +68 -0
  112. package/dist/services/runtime/adapters/openclaw-routes.js.map +1 -1
  113. package/dist/services/runtime/adapters/openclaw.d.ts +90 -0
  114. package/dist/services/runtime/adapters/openclaw.js +957 -45
  115. package/dist/services/runtime/adapters/openclaw.js.map +1 -1
  116. package/dist/services/runtime/instance.d.ts +1 -1
  117. package/dist/services/runtime/instance.js +1 -1
  118. package/dist/services/runtime/instance.js.map +1 -1
  119. package/dist/services/runtime/mcp-shims/anythingllm-shim.d.ts +46 -0
  120. package/dist/services/runtime/mcp-shims/anythingllm-shim.js +281 -0
  121. package/dist/services/runtime/mcp-shims/anythingllm-shim.js.map +1 -0
  122. package/dist/services/runtime/mcp-shims/drive-shim.d.ts +54 -0
  123. package/dist/services/runtime/mcp-shims/drive-shim.js +489 -0
  124. package/dist/services/runtime/mcp-shims/drive-shim.js.map +1 -0
  125. package/dist/services/runtime/types.d.ts +31 -0
  126. package/dist/services/setup-manager.js +93 -18
  127. package/dist/services/setup-manager.js.map +1 -1
  128. package/dist/services/suggestions.js.map +1 -1
  129. package/dist/services/webdav/server.d.ts +24 -0
  130. package/dist/services/webdav/server.js +420 -0
  131. package/dist/services/webdav/server.js.map +1 -0
  132. package/dist/services/webdav/xml-builder.d.ts +73 -0
  133. package/dist/services/webdav/xml-builder.js +156 -0
  134. package/dist/services/webdav/xml-builder.js.map +1 -0
  135. package/dist/services/workspace-builder.d.ts +29 -0
  136. package/dist/services/workspace-builder.js +188 -0
  137. package/dist/services/workspace-builder.js.map +1 -0
  138. package/dist/types.d.ts +60 -0
  139. package/dist/utils/path-locks.d.ts +30 -0
  140. package/dist/utils/path-locks.js +63 -0
  141. package/dist/utils/path-locks.js.map +1 -0
  142. package/dist/utils/path-safety.d.ts +41 -0
  143. package/dist/utils/path-safety.js +119 -0
  144. package/dist/utils/path-safety.js.map +1 -0
  145. package/dist/utils/safe-write.d.ts +24 -0
  146. package/dist/utils/safe-write.js +82 -0
  147. package/dist/utils/safe-write.js.map +1 -0
  148. package/package.json +16 -1
  149. package/public/assets/Dashboard-BdWPtroF.js +1 -0
  150. package/public/assets/{HermesChatPanel-_GHoklgo.js → HermesChatPanel-B_2HlVBQ.js} +1 -1
  151. package/public/assets/{HermesConfigForm-anDnwUp_.js → HermesConfigForm-DVlhg3WV.js} +2 -2
  152. package/public/assets/{InitPassword-ZU9_-hDr.js → InitPassword-D7glTExX.js} +1 -1
  153. package/public/assets/InstanceDetail-CxSy2cpe.js +92 -0
  154. package/public/assets/{Login-BItXqYAJ.js → Login-Cfr5c2sv.js} +1 -1
  155. package/public/assets/NewInstance-BIYDmJis.js +1 -0
  156. package/public/assets/{ProviderRecommendations-DFYj7Fb6.js → ProviderRecommendations-BuRnvRcI.js} +1 -1
  157. package/public/assets/{Settings-Bttc6QmM.js → Settings-Cc-tYBil.js} +1 -1
  158. package/public/assets/{Setup-Bsxx1zgj.js → Setup-lGZEk5jq.js} +1 -1
  159. package/public/assets/{WeixinLoginPanel-DPZpAKgO.js → WeixinLoginPanel-CoGqzxeV.js} +2 -2
  160. package/public/assets/index-87IJXG-w.css +1 -0
  161. package/public/assets/index-BZc5zH7u.js +19 -0
  162. package/public/assets/{registry-5s2UB6is.js → registry-BWnkJgZ1.js} +2 -2
  163. package/public/assets/{usePolling-Do5Erqm_.js → usePolling-CwwT9KrC.js} +1 -1
  164. package/public/assets/{vendor-i18n-ucpM0OR0.js → vendor-i18n-y9V7Sfuu.js} +1 -1
  165. package/public/assets/{vendor-react-Bk1hRGiY.js → vendor-react-BWrEVJVb.js} +6 -6
  166. package/public/index.html +4 -4
  167. package/scripts/check-app-spec.mjs +18 -4
  168. package/scripts/check-new-file-tests.mjs +230 -0
  169. package/scripts/check-quarantine-expiry.mjs +105 -0
  170. package/scripts/perf/README.md +49 -0
  171. package/scripts/perf/auth.js +99 -0
  172. package/scripts/perf/config.js +63 -0
  173. package/scripts/perf/instances.js +143 -0
  174. package/scripts/perf/proxy.js +96 -0
  175. package/scripts/smoke/files-w1.sh +142 -0
  176. package/scripts/smoke-backend.mjs +122 -0
  177. package/scripts/smoke-post-publish.mjs +346 -0
  178. package/public/assets/Dashboard-rkWp-CXd.js +0 -1
  179. package/public/assets/InstanceDetail-CN0FH1aw.js +0 -92
  180. package/public/assets/NewInstance-BousE6kY.js +0 -1
  181. package/public/assets/index-8xZy1z5k.css +0 -1
  182. package/public/assets/index-Dw3HhUYE.js +0 -19
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/routes/system.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/routes/system.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * /webdav/* routes (M3 W4 PR-3).
3
+ *
4
+ * Mounted as a Fastify plugin so the route-scoped octet-stream parser
5
+ * does not leak. Authentication runs as an onRequest hook upstream of
6
+ * the handlers — every request must carry Basic Auth resolving to a
7
+ * non-revoked app password.
8
+ *
9
+ * The mount path is fixed at /webdav (no instance-specific suffix);
10
+ * the root maps to ~/.jishushell/files/.
11
+ */
12
+ import type { FastifyInstance } from "fastify";
13
+ import { FilesManager } from "../services/files-manager.js";
14
+ export interface WebdavRoutesDeps {
15
+ filesManager: FilesManager;
16
+ }
17
+ export declare function webdavRoutes(app: FastifyInstance, deps: WebdavRoutesDeps): Promise<void>;
@@ -0,0 +1,114 @@
1
+ import { parseBasicAuth, verifyAppPassword, } from "../services/app-passwords.js";
2
+ import { handleOptions, handlePropfind, handleGet, handlePut, handleDelete, handleMkcol, handleMove, handleCopy, } from "../services/webdav/server.js";
3
+ const MOUNT_PREFIX = "/webdav";
4
+ export async function webdavRoutes(app, deps) {
5
+ // ── Register WebDAV-specific HTTP methods ──────
6
+ // Fastify 5 supports any method via addHttpMethod. PROPFIND has a
7
+ // body (XML); MKCOL/MOVE/COPY don't.
8
+ app.addHttpMethod("PROPFIND", { hasBody: true });
9
+ app.addHttpMethod("MKCOL", { hasBody: false });
10
+ app.addHttpMethod("MOVE", { hasBody: false });
11
+ app.addHttpMethod("COPY", { hasBody: false });
12
+ app.addHttpMethod("PROPPATCH", { hasBody: true });
13
+ app.addHttpMethod("LOCK", { hasBody: true });
14
+ app.addHttpMethod("UNLOCK", { hasBody: false });
15
+ app.addHttpMethod("REPORT", { hasBody: true });
16
+ // Pass-through parser for octet-stream PUT bodies (avoid bufferization)
17
+ app.addContentTypeParser("application/octet-stream", (_req, payload, done) => done(null, payload));
18
+ // PROPFIND clients send XML — accept it as a stream too; we don't
19
+ // actually parse the request XML (Depth header is enough for the
20
+ // properties we serve), so just consume and ignore.
21
+ app.addContentTypeParser(["application/xml", "text/xml"], (_req, payload, done) => done(null, payload));
22
+ // ── Authentication: Basic + app password ───────
23
+ app.addHook("onRequest", async (req, reply) => {
24
+ if (!req.url.startsWith(MOUNT_PREFIX))
25
+ return;
26
+ const auth = parseBasicAuth(req.headers.authorization);
27
+ if (!auth) {
28
+ reply
29
+ .code(401)
30
+ .header("WWW-Authenticate", 'Basic realm="JishuShell WebDAV"')
31
+ .send("authentication required");
32
+ return reply;
33
+ }
34
+ const [username, password] = auth;
35
+ const record = await verifyAppPassword(username, password);
36
+ if (!record) {
37
+ reply
38
+ .code(401)
39
+ .header("WWW-Authenticate", 'Basic realm="JishuShell WebDAV"')
40
+ .send("invalid credentials");
41
+ return reply;
42
+ }
43
+ req.appPassword = record;
44
+ });
45
+ // ── Method dispatcher ──────────────────────────
46
+ const dispatcher = async (req, reply) => {
47
+ const ctx = {
48
+ filesManager: deps.filesManager,
49
+ mountPrefix: MOUNT_PREFIX,
50
+ authedAs: req.appPassword,
51
+ };
52
+ const method = req.method.toUpperCase();
53
+ switch (method) {
54
+ case "OPTIONS":
55
+ return handleOptions(ctx, req, reply);
56
+ case "PROPFIND":
57
+ return handlePropfind(ctx, req, reply);
58
+ case "GET":
59
+ return handleGet(ctx, req, reply, false);
60
+ case "HEAD":
61
+ return handleGet(ctx, req, reply, true);
62
+ case "PUT":
63
+ return handlePut(ctx, req, reply);
64
+ case "DELETE":
65
+ return handleDelete(ctx, req, reply);
66
+ case "MKCOL":
67
+ return handleMkcol(ctx, req, reply);
68
+ case "MOVE":
69
+ return handleMove(ctx, req, reply);
70
+ case "COPY":
71
+ return handleCopy(ctx, req, reply);
72
+ case "PROPPATCH":
73
+ case "LOCK":
74
+ case "UNLOCK":
75
+ case "REPORT":
76
+ // Not implemented — return 501 so clients fall back gracefully
77
+ reply.code(501).send(`${method} not supported`);
78
+ return;
79
+ default:
80
+ reply.code(405).header("Allow", "OPTIONS, GET, HEAD, PUT, DELETE, PROPFIND, MKCOL, MOVE, COPY").send();
81
+ return;
82
+ }
83
+ };
84
+ const ALL_METHODS = [
85
+ "OPTIONS",
86
+ "GET",
87
+ "HEAD",
88
+ "PUT",
89
+ "DELETE",
90
+ "PROPFIND",
91
+ "MKCOL",
92
+ "MOVE",
93
+ "COPY",
94
+ "PROPPATCH",
95
+ "LOCK",
96
+ "UNLOCK",
97
+ "REPORT",
98
+ ];
99
+ // 50MB body limit matches /api/files. WebDAV PUT on bigger files
100
+ // requires a separate "chunked upload" extension we'll add later.
101
+ app.route({
102
+ method: ALL_METHODS,
103
+ url: MOUNT_PREFIX,
104
+ bodyLimit: 50 * 1024 * 1024,
105
+ handler: dispatcher,
106
+ });
107
+ app.route({
108
+ method: ALL_METHODS,
109
+ url: `${MOUNT_PREFIX}/*`,
110
+ bodyLimit: 50 * 1024 * 1024,
111
+ handler: dispatcher,
112
+ });
113
+ }
114
+ //# sourceMappingURL=webdav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdav.js","sourceRoot":"","sources":["../../src/routes/webdav.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -8,7 +8,8 @@ import { request as httpRequest } from "http";
8
8
  import { request as httpsRequest } from "https";
9
9
  const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = dirname(__filename);
11
- import { ensureDirs, ensurePanelConfig, getPanelConfig, migrateCatalogSchemaIfNeeded, migrateHermesShimOutIfNeeded, migrateOpenclawCatalogIfNeeded, migrateOpenclawImageTagIfNeeded, } from "./config.js";
11
+ import { ensureDirs, ensurePanelConfig, getPanelConfig, migrateCatalogSchemaIfNeeded, migrateHermesShimOutIfNeeded, migrateOpenclawCatalogIfNeeded, migrateOpenclawImageTagIfNeeded, getInternalMcpToken, } from "./config.js";
12
+ import { timingSafeEqual } from "node:crypto";
12
13
  import { runStartupMigrations } from "./services/runtime/index.js";
13
14
  import { verifyToken } from "./auth.js";
14
15
  import { authRoutes } from "./routes/auth.js";
@@ -19,6 +20,13 @@ import { runtimeCatalogRoutes } from "./routes/runtime.js";
19
20
  import { appRoutes } from "./routes/apps.js";
20
21
  import { agentAppRoutes } from "./routes/agent-apps.js";
21
22
  import { llmRoutes } from "./routes/llm.js";
23
+ import { filesRoutes } from "./routes/files.js";
24
+ import { internalRoutes } from "./routes/internal.js";
25
+ import { organizeRoutes } from "./routes/files-organize.js";
26
+ import { fileMountsRoutes } from "./routes/file-mounts.js";
27
+ import { webdavRoutes } from "./routes/webdav.js";
28
+ import { externalMountsRoutes } from "./routes/external-mounts.js";
29
+ import { FilesManager } from "./services/files-manager.js";
22
30
  import * as appManager from "./services/app/app-manager.js";
23
31
  import * as capabilityRegistry from "./services/capability-registry.js";
24
32
  import backupRoutes from "./routes/backup.js";
@@ -31,6 +39,28 @@ import { checkUpdate } from "./services/panel-manager.js";
31
39
  import { PROXY_IDENTITY_HEADERS } from "./constants.js";
32
40
  import { supportsGatewayWebsocket } from "./services/runtime/instance.js";
33
41
  const PUBLIC_PATHS = new Set(["/api/auth/status", "/api/auth/init", "/api/auth/login", "/api/setup/status", "/api/apps/validate-sudo-password"]);
42
+ /** Slug charset for /apps/:slug — same as instance ids. */
43
+ const SLUG_RE = /^[a-z0-9][a-z0-9-]{0,62}$/;
44
+ /** Regex for top-level app WebSocket upgrades (AI-FS v1 W2.5 PR-8). */
45
+ const APP_SLUG_WS_RE = /^\/apps\/([a-z0-9][a-z0-9-]{0,62})(\/.*)?$/;
46
+ /**
47
+ * Resolve the upstream host/port for a top-level /apps/:slug request using
48
+ * the capability registry. Resolution order:
49
+ * 1. `<slug>-ui` — canonical convention (e.g. filebrowser-ui)
50
+ * 2. `web-<slug>` — web-* convention (e.g. web-filebrowser)
51
+ * Returns the first entry with status === "running", or null if none found.
52
+ */
53
+ function resolveAppSlugUpstream(slug) {
54
+ const candidates = [`${slug}-ui`, `web-${slug}`];
55
+ for (const cap of candidates) {
56
+ const providers = capabilityRegistry.listProviders(cap);
57
+ const running = providers.find((p) => p.status === "running");
58
+ if (running) {
59
+ return { host: running.host, port: running.hostPort };
60
+ }
61
+ }
62
+ return null;
63
+ }
34
64
  function hasValidPanelUpgradeToken(req) {
35
65
  const authHeader = req.headers.authorization || "";
36
66
  const match = authHeader.match(/^Bearer\s+(\S+)$/);
@@ -123,7 +153,7 @@ export async function createServer(options = {}) {
123
153
  bodyLimit: 1048576,
124
154
  });
125
155
  // Allow empty JSON body for POST requests
126
- app.addContentTypeParser("application/json", { parseAs: "string" }, (req, body, done) => {
156
+ app.addContentTypeParser("application/json", { parseAs: "string" }, (_req, body, done) => {
127
157
  if (!body || body.length === 0) {
128
158
  done(null, {});
129
159
  }
@@ -137,9 +167,49 @@ export async function createServer(options = {}) {
137
167
  }
138
168
  });
139
169
  // Parse text/plain and application/x-yaml as raw string (for app install endpoint)
140
- app.addContentTypeParser(["text/plain", "application/x-yaml"], { parseAs: "string" }, (req, body, done) => {
170
+ app.addContentTypeParser(["text/plain", "application/x-yaml"], { parseAs: "string" }, (_req, body, done) => {
141
171
  done(null, body);
142
172
  });
173
+ // Fallback: pass any other content type through as the raw stream. Without
174
+ // this, /apps/:slug/* (W2.5 PR-8) would reject POST/PUT uploads with 415
175
+ // because Fastify's default behavior is to reject unparseable bodies.
176
+ // Specific routes that need typed bodies (octet-stream upload, etc.)
177
+ // register their own narrower parsers — those win over this catch-all.
178
+ app.addContentTypeParser("*", (_req, payload, done) => {
179
+ done(null, payload);
180
+ });
181
+ // Eager-init the internal MCP token so the file exists on disk before
182
+ // any agent container starts and tries to read it via env injection.
183
+ // Lazy-init would only fire on the first request that carries an
184
+ // X-Jishushell-Internal-Token header, which is too late for the
185
+ // adapter onBeforeStart that mounts the value into the container.
186
+ try {
187
+ getInternalMcpToken();
188
+ }
189
+ catch (e) {
190
+ console.warn(`[server] internal MCP token init skipped: ${e?.message ?? e}`);
191
+ }
192
+ // ── Auth middleware for /apps/* (AI-FS v1 W2.5 PR-8) ──────────────────
193
+ // Top-level reverse proxy for installed apps. Added in AI-FS v1 W2.5 PR-8.
194
+ // Pairs with `/api/instances/:id/provides/:cap/*` which is instance-scoped.
195
+ // This hook is scoped to /apps/* only so it does not double-fire with the
196
+ // existing /api/* hook below.
197
+ app.addHook("onRequest", async (request, reply) => {
198
+ const path = request.url.split("?")[0];
199
+ if (!path.startsWith("/apps/"))
200
+ return;
201
+ const authHeader = request.headers.authorization || "";
202
+ const match = authHeader.match(/^Bearer\s+(\S+)$/);
203
+ let token = match?.[1] || "";
204
+ if (!token) {
205
+ const cookie = request.headers.cookie || "";
206
+ const cookieMatch = cookie.match(/(?:^|;\s*)jishushell_session=([^;]*)/);
207
+ token = cookieMatch?.[1] || "";
208
+ }
209
+ if (!token || token.length > 4096 || !verifyToken(token)) {
210
+ return reply.status(401).send({ detail: "Unauthorized" });
211
+ }
212
+ });
143
213
  // Auth middleware
144
214
  app.addHook("onRequest", async (request, reply) => {
145
215
  const path = request.url.split("?")[0];
@@ -154,6 +224,35 @@ export async function createServer(options = {}) {
154
224
  }
155
225
  return;
156
226
  }
227
+ // Internal token path — used by:
228
+ // (a) MCP shims spawned inside agent containers
229
+ // (need BOTH X-Jishushell-Internal-Token + X-Jishushell-Instance)
230
+ // (b) Panel app lifecycle scripts (post_start, etc.) calling back into
231
+ // /api/internal/* on the same host
232
+ // (need ONLY X-Jishushell-Internal-Token; no instance binding —
233
+ // apps aren't instances)
234
+ // Combined with the standard JWT path below; we never require both.
235
+ const internalToken = request.headers["x-jishushell-internal-token"];
236
+ if (typeof internalToken === "string" && internalToken.length >= 32) {
237
+ const expected = getInternalMcpToken();
238
+ if (internalToken.length === expected.length &&
239
+ timingSafeEqual(Buffer.from(internalToken), Buffer.from(expected))) {
240
+ const instanceId = request.headers["x-jishushell-instance"];
241
+ if (typeof instanceId === "string" && instanceManager.getInstance(instanceId)) {
242
+ request.internalCallerInstance = instanceId;
243
+ return;
244
+ }
245
+ // Path (b): app-lifecycle / internal-only routes. Allowed without
246
+ // an instance header. The route is responsible for asserting the
247
+ // (request as any).internalCallerScope === "panel" tag before
248
+ // returning sensitive data.
249
+ if (path.startsWith("/api/internal/")) {
250
+ request.internalCallerScope = "panel";
251
+ return;
252
+ }
253
+ }
254
+ return reply.status(401).send({ detail: "Unauthorized" });
255
+ }
157
256
  // Check Authorization header first, then fall back to httpOnly cookie
158
257
  const authHeader = request.headers.authorization || "";
159
258
  const match = authHeader.match(/^Bearer\s+(\S+)$/);
@@ -201,6 +300,122 @@ export async function createServer(options = {}) {
201
300
  await app.register(agentAppRoutes);
202
301
  await app.register(llmRoutes);
203
302
  await app.register(backupRoutes);
303
+ await app.register(internalRoutes);
304
+ // Single FilesManager instance shared across /api/files, /webdav, and
305
+ // /api/files/external-mounts so a mutation on the mount list (PUT
306
+ // /external-mounts) is visible to every layer immediately.
307
+ const panelCfgForFiles = getPanelConfig();
308
+ const initialExternalMounts = Array.isArray(panelCfgForFiles.external_mounts)
309
+ ? panelCfgForFiles.external_mounts
310
+ : [];
311
+ const sharedFilesManager = new FilesManager({
312
+ externalMounts: initialExternalMounts,
313
+ });
314
+ await app.register(async (scope) => {
315
+ // Encapsulated registration so the route-scoped octet-stream parser
316
+ // does not leak to other routes (matches plan G6/D6 — Files is the
317
+ // only route that needs raw-stream uploads at W1).
318
+ await filesRoutes(scope, { filesManager: sharedFilesManager });
319
+ await organizeRoutes(scope, { filesManager: sharedFilesManager });
320
+ await fileMountsRoutes(scope);
321
+ await externalMountsRoutes(scope, { filesManager: sharedFilesManager });
322
+ });
323
+ // WebDAV runs in its own scope — it has independent auth (app password
324
+ // Basic Auth, NOT the panel JWT) and registers extra HTTP methods that
325
+ // we don't want leaking to other routes.
326
+ await app.register(async (scope) => {
327
+ await webdavRoutes(scope, { filesManager: sharedFilesManager });
328
+ });
329
+ // ── Top-level /apps/:slug/* reverse proxy (AI-FS v1 W2.5 PR-8) ───────────
330
+ // Reverse-proxies HTTP requests for installed apps to their capability
331
+ // upstream. Auth is handled by the onRequest hook above. The /apps/:slug
332
+ // prefix is NOT stripped — apps like Filebrowser are configured with
333
+ // --baseURL=/apps/filebrowser and expect the full path.
334
+ //
335
+ // Resolution order: `<slug>-ui` → `web-<slug>` (first running entry wins).
336
+ // 503 if no running provider found. 400 if slug is malformed.
337
+ //
338
+ // Registered BEFORE the SPA static fallback so explicit routes win.
339
+ const appsProxyHandler = async (req, reply) => {
340
+ const rawSlug = req.params.slug ?? "";
341
+ if (!SLUG_RE.test(rawSlug)) {
342
+ return reply.status(400).send({ detail: "Invalid app slug", slug: rawSlug });
343
+ }
344
+ const upstream = resolveAppSlugUpstream(rawSlug);
345
+ if (!upstream) {
346
+ return reply.status(503).send({ detail: "app not running", slug: rawSlug });
347
+ }
348
+ const { host: upstreamHost, port: upstreamPort } = upstream;
349
+ // Pass the full original path unchanged (including /apps/<slug> prefix).
350
+ const rawUrl = req.raw.url ?? "/";
351
+ const targetPath = rawUrl;
352
+ const hostHeader = `${upstreamHost}:${upstreamPort}`;
353
+ // Build forwarded headers: strip cookie and authorization to avoid
354
+ // leaking panel session credentials to third-party apps.
355
+ const forwardHeaders = {};
356
+ for (const [key, value] of Object.entries(req.headers)) {
357
+ if (value === undefined)
358
+ continue;
359
+ const lower = key.toLowerCase();
360
+ if (lower === "host")
361
+ continue;
362
+ if (lower === "cookie") {
363
+ const stripped = stripPanelSessionCookie(value);
364
+ if (stripped)
365
+ forwardHeaders[key] = stripped;
366
+ continue;
367
+ }
368
+ if (lower === "authorization")
369
+ continue;
370
+ forwardHeaders[key] = value;
371
+ }
372
+ forwardHeaders["host"] = hostHeader;
373
+ // Hijack before writing to reply.raw so Fastify does not attempt its own
374
+ // lifecycle send after the handler returns.
375
+ reply.hijack();
376
+ await new Promise((resolve) => {
377
+ const proxyReq = httpRequest({
378
+ hostname: upstreamHost,
379
+ port: upstreamPort,
380
+ path: targetPath,
381
+ method: req.method,
382
+ headers: forwardHeaders,
383
+ }, (proxyRes) => {
384
+ // Stream the response back without buffering.
385
+ reply.raw.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);
386
+ proxyRes.pipe(reply.raw, { end: true });
387
+ proxyRes.on("end", resolve);
388
+ proxyRes.on("error", () => {
389
+ try {
390
+ reply.raw.end();
391
+ }
392
+ catch { }
393
+ resolve();
394
+ });
395
+ });
396
+ proxyReq.on("error", (err) => {
397
+ console.error(`[apps-proxy] upstream error for slug=${rawSlug}:`, err.message);
398
+ if (!reply.raw.headersSent) {
399
+ reply.raw.writeHead(502, { "content-type": "application/json" });
400
+ reply.raw.end(JSON.stringify({ detail: "upstream error", slug: rawSlug }));
401
+ }
402
+ resolve();
403
+ });
404
+ // Forward request body if present (POST, PUT, PATCH, etc.)
405
+ if (req.rawBody) {
406
+ proxyReq.end(req.rawBody);
407
+ }
408
+ else if (req.raw.readable) {
409
+ req.raw.pipe(proxyReq, { end: true });
410
+ req.raw.on("end", () => { }); // ensure event fires
411
+ }
412
+ else {
413
+ proxyReq.end();
414
+ }
415
+ });
416
+ };
417
+ app.all("/apps/:slug", appsProxyHandler);
418
+ app.all("/apps/:slug/*", appsProxyHandler);
204
419
  // Serve frontend static files
205
420
  // Look for frontend dist in multiple locations
206
421
  const resolvedDir = existsSync(__dirname) ? realpathSync(__dirname) : __dirname;
@@ -408,6 +623,129 @@ export async function createServer(options = {}) {
408
623
  const path = url.split("?")[0];
409
624
  const gatewayMatch = path.match(GATEWAY_WS_RE);
410
625
  const capabilityMatch = path.match(CAPABILITY_WS_RE);
626
+ // ── /apps/:slug/* WebSocket upgrade (AI-FS v1 W2.5 PR-8) ──────────────
627
+ // Proxy WS upgrades for top-level installed apps. Same auth gate as HTTP.
628
+ const appSlugWsMatch = path.match(APP_SLUG_WS_RE);
629
+ if (appSlugWsMatch && !gatewayMatch && !capabilityMatch) {
630
+ const slug = appSlugWsMatch[1];
631
+ // Auth gate: same JWT cookie/bearer check as the HTTP handler above.
632
+ if (!hasValidPanelUpgradeToken(req)) {
633
+ socket.write("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
634
+ socket.destroy();
635
+ return;
636
+ }
637
+ const upstream = resolveAppSlugUpstream(slug);
638
+ if (!upstream) {
639
+ socket.write("HTTP/1.1 503 Service Unavailable\r\nConnection: close\r\n\r\n");
640
+ socket.destroy();
641
+ return;
642
+ }
643
+ const { host: upstreamHost, port: upstreamPort } = upstream;
644
+ const hostHeader = `${upstreamHost}:${upstreamPort}`;
645
+ const upstreamOrigin = `http://${hostHeader}`;
646
+ const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
647
+ const targetPath = `${path}${qs}`;
648
+ // Build upstream WS headers: strip cookie (panel session) and authorization.
649
+ const upstreamHeaders = buildCapabilityWebSocketHeaders(req.headers, upstreamOrigin);
650
+ socket.setTimeout?.(0);
651
+ socket.setNoDelay?.(true);
652
+ socket.setKeepAlive?.(true, 30000);
653
+ let proxyReq;
654
+ try {
655
+ proxyReq = httpRequest({
656
+ hostname: upstreamHost,
657
+ port: upstreamPort,
658
+ path: targetPath,
659
+ method: "GET",
660
+ timeout: 10_000,
661
+ headers: {
662
+ ...upstreamHeaders,
663
+ host: hostHeader,
664
+ },
665
+ });
666
+ }
667
+ catch {
668
+ try {
669
+ socket.destroy();
670
+ }
671
+ catch { }
672
+ activeWsSockets.delete(socket);
673
+ return;
674
+ }
675
+ proxyReq.on("timeout", () => {
676
+ proxyReq.destroy();
677
+ socket.destroy();
678
+ });
679
+ proxyReq.on("upgrade", (_res, proxySocket, proxyHead) => {
680
+ proxySocket.setTimeout(0);
681
+ proxySocket.setNoDelay(true);
682
+ proxySocket.setKeepAlive(true, 30000);
683
+ proxySocket.pause();
684
+ let handshake = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n";
685
+ for (const [k, v] of Object.entries(_res.headers)) {
686
+ if (v !== undefined && k.toLowerCase().startsWith("sec-websocket-")) {
687
+ handshake += `${k}: ${v}\r\n`;
688
+ }
689
+ }
690
+ handshake += "\r\n";
691
+ socket.write(handshake);
692
+ if (head.length > 0)
693
+ proxySocket.write(head);
694
+ if (proxyHead.length > 0)
695
+ socket.write(proxyHead);
696
+ proxySocket.pipe(socket);
697
+ socket.pipe(proxySocket);
698
+ proxySocket.resume();
699
+ activeWsSockets.add(socket);
700
+ activeWsSockets.add(proxySocket);
701
+ const release = (s) => { activeWsSockets.delete(s); };
702
+ const fail = () => {
703
+ try {
704
+ proxySocket.destroy();
705
+ }
706
+ catch { }
707
+ try {
708
+ socket.destroy();
709
+ }
710
+ catch { }
711
+ release(socket);
712
+ release(proxySocket);
713
+ };
714
+ proxySocket.on("close", () => {
715
+ release(proxySocket);
716
+ try {
717
+ if (!socket.destroyed && !socket.writableEnded)
718
+ socket.end();
719
+ }
720
+ catch { }
721
+ });
722
+ socket.on("close", () => {
723
+ release(socket);
724
+ try {
725
+ if (!proxySocket.destroyed && !proxySocket.writableEnded)
726
+ proxySocket.end();
727
+ }
728
+ catch { }
729
+ });
730
+ proxySocket.on("error", fail);
731
+ socket.on("error", fail);
732
+ });
733
+ proxyReq.on("response", (res) => {
734
+ forwardWebSocketRejection(socket, res);
735
+ activeWsSockets.delete(socket);
736
+ });
737
+ proxyReq.on("error", () => {
738
+ try {
739
+ socket.write("HTTP/1.1 502 Bad Gateway\r\nConnection: close\r\n\r\n");
740
+ }
741
+ catch { }
742
+ socket.destroy();
743
+ activeWsSockets.delete(socket);
744
+ });
745
+ proxyReq.end();
746
+ return;
747
+ }
748
+ // ── end /apps/:slug/* WS upgrade ───────────────────────────────────────
411
749
  // When an embedded page (e.g. Browserless debugger's puppeteer Worker)
412
750
  // opens a WS to the panel origin at a non-API path (e.g. /?launch=...),
413
751
  // resolve the target instance via the Referer header pointing at the