@beastmode-develeap/beastmode 0.1.323 → 0.1.325
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 +26 -5
- 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
|
@@ -6387,8 +6387,19 @@ function getBoardRoutes(factoryDir) {
|
|
|
6387
6387
|
const repoName = url.replace(/\.git$/, "").split(/[/:]/).filter(Boolean).pop() || "";
|
|
6388
6388
|
if (!repoName) throw new Error("Could not derive repo name from URL");
|
|
6389
6389
|
const baseDir = clone_target ? resolve4(clone_target) : process.env.BEASTMODE_CLONE_DIR ? resolve4(process.env.BEASTMODE_CLONE_DIR) : join14(homedir(), "repos");
|
|
6390
|
+
const allowedRoots = _getAllowedRoots();
|
|
6391
|
+
if (!_isPathAllowed(baseDir, allowedRoots)) {
|
|
6392
|
+
throw new Error(
|
|
6393
|
+
`clone_target not allowed: ${baseDir} is outside the configured allowlist`
|
|
6394
|
+
);
|
|
6395
|
+
}
|
|
6390
6396
|
if (!existsSync16(baseDir)) mkdirSync12(baseDir, { recursive: true });
|
|
6391
6397
|
resolvedPath = join14(baseDir, repoName);
|
|
6398
|
+
if (!_isPathAllowed(resolvedPath, allowedRoots)) {
|
|
6399
|
+
throw new Error(
|
|
6400
|
+
`clone_target not allowed: ${resolvedPath} is outside the configured allowlist`
|
|
6401
|
+
);
|
|
6402
|
+
}
|
|
6392
6403
|
if (existsSync16(resolvedPath)) {
|
|
6393
6404
|
throw new Error(`Target path already exists: ${resolvedPath} \u2014 pick a different clone_target or rename the existing folder`);
|
|
6394
6405
|
}
|
|
@@ -7647,10 +7658,19 @@ async function startServer(options = {}) {
|
|
|
7647
7658
|
}
|
|
7648
7659
|
}
|
|
7649
7660
|
}
|
|
7650
|
-
if (UI_PASSWORD
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7661
|
+
if (UI_PASSWORD) {
|
|
7662
|
+
if (!isAuthExempt(method, url) && !isAuthenticated(req)) {
|
|
7663
|
+
res.writeHead(302, { Location: "/auth/login" });
|
|
7664
|
+
res.end();
|
|
7665
|
+
return;
|
|
7666
|
+
}
|
|
7667
|
+
} else if (!ALLOW_NO_AUTH) {
|
|
7668
|
+
if (url.startsWith("/api/") && !isAuthExempt(method, url)) {
|
|
7669
|
+
sendJson(res, 403, {
|
|
7670
|
+
error: "Board API authentication is not configured. Set BEASTMODE_UI_PASSWORD, or set BEASTMODE_ALLOW_NO_AUTH=true to explicitly allow unauthenticated access."
|
|
7671
|
+
});
|
|
7672
|
+
return;
|
|
7673
|
+
}
|
|
7654
7674
|
}
|
|
7655
7675
|
if (url === "/auth/login" && method === "GET") {
|
|
7656
7676
|
if (!UI_PASSWORD || isAuthenticated(req)) {
|
|
@@ -7920,7 +7940,7 @@ async function startServer(options = {}) {
|
|
|
7920
7940
|
});
|
|
7921
7941
|
});
|
|
7922
7942
|
}
|
|
7923
|
-
var _boardWsProxy, __filename, __dirname, INACTIVITY_TIMEOUT_MS, UI_PASSWORD, AUTH_COOKIE_NAME, AUTH_COOKIE_MAX_AGE, LOGIN_PAGE;
|
|
7943
|
+
var _boardWsProxy, __filename, __dirname, INACTIVITY_TIMEOUT_MS, UI_PASSWORD, ALLOW_NO_AUTH, AUTH_COOKIE_NAME, AUTH_COOKIE_MAX_AGE, LOGIN_PAGE;
|
|
7924
7944
|
var init_server = __esm({
|
|
7925
7945
|
"src/cli/ui/server.ts"() {
|
|
7926
7946
|
"use strict";
|
|
@@ -7932,6 +7952,7 @@ var init_server = __esm({
|
|
|
7932
7952
|
__dirname = dirname6(__filename);
|
|
7933
7953
|
INACTIVITY_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
7934
7954
|
UI_PASSWORD = process.env.BEASTMODE_UI_PASSWORD || "";
|
|
7955
|
+
ALLOW_NO_AUTH = /^(1|true|yes)$/i.test(process.env.BEASTMODE_ALLOW_NO_AUTH || "");
|
|
7935
7956
|
AUTH_COOKIE_NAME = "bm_session";
|
|
7936
7957
|
AUTH_COOKIE_MAX_AGE = 86400;
|
|
7937
7958
|
LOGIN_PAGE = `<!DOCTYPE html>
|