@beastmode-develeap/beastmode 0.1.314 → 0.1.316
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.
- package/dist/index.js +39 -1
- package/dist/index.js.map +1 -1
- package/dist/web/board.html +1 -1
- package/dist/web/build-commit.txt +1 -1
- package/dist/web/build-stamp.txt +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5257,11 +5257,43 @@ var init_chat_handler = __esm({
|
|
|
5257
5257
|
|
|
5258
5258
|
// src/cli/ui/board-api-routes.ts
|
|
5259
5259
|
import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, existsSync as existsSync16, readdirSync as readdirSync8, unlinkSync as unlinkSync4, mkdirSync as mkdirSync12, statSync as statSync6, rmSync as rmSync3 } from "fs";
|
|
5260
|
-
import { join as join14, basename as basename5, resolve as resolve4, dirname as dirname5 } from "path";
|
|
5260
|
+
import { join as join14, basename as basename5, resolve as resolve4, dirname as dirname5, sep } from "path";
|
|
5261
5261
|
import { homedir } from "os";
|
|
5262
5262
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5263
5263
|
import { execSync as execSync3, spawnSync } from "child_process";
|
|
5264
5264
|
import http2 from "http";
|
|
5265
|
+
function _getAllowedRoots() {
|
|
5266
|
+
const roots = [];
|
|
5267
|
+
const homeRaw = process.env.HOME && process.env.HOME.length > 0 ? process.env.HOME : homedir();
|
|
5268
|
+
roots.push(resolve4(homeRaw));
|
|
5269
|
+
const projectDir = process.env.PROJECT_DIR;
|
|
5270
|
+
if (projectDir && projectDir.length > 0) {
|
|
5271
|
+
roots.push(resolve4(projectDir));
|
|
5272
|
+
}
|
|
5273
|
+
const cloneDir = process.env.BEASTMODE_CLONE_DIR;
|
|
5274
|
+
if (cloneDir && cloneDir.length > 0) {
|
|
5275
|
+
roots.push(resolve4(cloneDir));
|
|
5276
|
+
}
|
|
5277
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5278
|
+
const deduped = [];
|
|
5279
|
+
for (const r of roots) {
|
|
5280
|
+
if (!seen.has(r)) {
|
|
5281
|
+
seen.add(r);
|
|
5282
|
+
deduped.push(r);
|
|
5283
|
+
}
|
|
5284
|
+
}
|
|
5285
|
+
return deduped;
|
|
5286
|
+
}
|
|
5287
|
+
function _isPathAllowed(targetPath, roots) {
|
|
5288
|
+
if (roots.length === 0) return false;
|
|
5289
|
+
const target = resolve4(targetPath);
|
|
5290
|
+
for (const r of roots) {
|
|
5291
|
+
const root = resolve4(r);
|
|
5292
|
+
if (target === root) return true;
|
|
5293
|
+
if (target.startsWith(root + sep)) return true;
|
|
5294
|
+
}
|
|
5295
|
+
return false;
|
|
5296
|
+
}
|
|
5265
5297
|
function assertSafeName(name) {
|
|
5266
5298
|
if (!name || /[/\\]/.test(name) || name === "." || name === "..") {
|
|
5267
5299
|
throw new Error(`Invalid name: ${name}`);
|
|
@@ -6308,6 +6340,12 @@ function getBoardRoutes(factoryDir) {
|
|
|
6308
6340
|
const { path: queryPath } = body || {};
|
|
6309
6341
|
const startPath = queryPath || homedir();
|
|
6310
6342
|
const target = resolve4(startPath);
|
|
6343
|
+
const allowedRoots = _getAllowedRoots();
|
|
6344
|
+
if (!_isPathAllowed(target, allowedRoots)) {
|
|
6345
|
+
throw new Error(
|
|
6346
|
+
`Path not allowed: ${target} is outside the configured allowlist`
|
|
6347
|
+
);
|
|
6348
|
+
}
|
|
6311
6349
|
if (!existsSync16(target)) throw new Error(`Path not found: ${target}`);
|
|
6312
6350
|
const st = statSync6(target);
|
|
6313
6351
|
if (!st.isDirectory()) throw new Error(`Not a directory: ${target}`);
|