@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 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 && !isAuthExempt(method, url) && !isAuthenticated(req)) {
7651
- res.writeHead(302, { Location: "/auth/login" });
7652
- res.end();
7653
- return;
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>