Anurag commited on
Commit
e511ea7
Β·
unverified Β·
2 Parent(s): 4db8e0573d2e96

Merge pull request #115 from anurag008w/codex/fix-bugs-in-start.sh,-health-server.js,-env-builder.js,-env-y8p5pn

Browse files
Files changed (3) hide show
  1. health-server.js +13 -7
  2. multi-provider-key-rotator.cjs +7 -0
  3. start.sh +1 -11
health-server.js CHANGED
@@ -22,12 +22,13 @@ const JUPYTER_HOST = "127.0.0.1";
22
  const JUPYTER_BASE = normalizeBase(process.env.JUPYTER_BASE, "/terminal");
23
  const GATEWAY_TOKEN = (process.env.GATEWAY_TOKEN || "").trim();
24
  const DEV_MODE_ENABLED = isTrue(process.env.DEV_MODE);
25
- // Default true. Only false when DEV_MODE=false or HUGGINGCLAW_JUPYTER_ENABLED=false is explicitly set.
 
26
  // HUGGINGCLAW_JUPYTER_ENABLED=true is the explicit user override and always wins.
27
  const JUPYTER_ENABLED =
28
  /^(true|1|yes|on)$/i.test(String(process.env.HUGGINGCLAW_JUPYTER_ENABLED || "").trim()) ||
29
  (
30
- !/^(false|0|no|off)$/i.test(String(process.env.DEV_MODE || "").trim()) &&
31
  !/^(false|0|no|off)$/i.test(String(process.env.HUGGINGCLAW_JUPYTER_ENABLED || "").trim())
32
  );
33
  const startTime = Date.now();
@@ -252,9 +253,14 @@ function parseCookies(req) {
252
 
253
  // Constant-time comparison β€” prevent timing attacks on token check
254
  function safeEqual(a, b) {
255
- if (typeof a !== "string" || typeof b !== "string" || a.length !== b.length) return false;
256
- let d = 0;
257
- for (let i = 0; i < a.length; i++) d |= a.charCodeAt(i) ^ b.charCodeAt(i);
 
 
 
 
 
258
  return d === 0;
259
  }
260
 
@@ -668,7 +674,7 @@ const server = http.createServer(async (req, res) => {
668
  const body = await readBody(req);
669
  const token = decodeURIComponent((body.match(/(?:^|&)token=([^&]*)/) || [])[1] || "").replace(/\+/g, " ");
670
  if (safeEqual(token, GATEWAY_TOKEN)) {
671
- const cookie = `hc_env_auth=${encodeURIComponent(GATEWAY_TOKEN)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400`;
672
  res.writeHead(302, { Location: "/env-builder", "Set-Cookie": cookie, "Cache-Control": "no-store" });
673
  return res.end();
674
  }
@@ -680,7 +686,7 @@ const server = http.createServer(async (req, res) => {
680
  }
681
 
682
  if (pathname === "/env-builder/logout") {
683
- res.writeHead(302, { Location: "/env-builder", "Set-Cookie": "hc_env_auth=; Path=/; HttpOnly; Max-Age=0", "Cache-Control": "no-store" });
684
  return res.end();
685
  }
686
 
 
22
  const JUPYTER_BASE = normalizeBase(process.env.JUPYTER_BASE, "/terminal");
23
  const GATEWAY_TOKEN = (process.env.GATEWAY_TOKEN || "").trim();
24
  const DEV_MODE_ENABLED = isTrue(process.env.DEV_MODE);
25
+ // Explicit HUGGINGCLAW_JUPYTER_ENABLED=true enables Jupyter.
26
+ // Otherwise DEV_MODE=true enables it unless HUGGINGCLAW_JUPYTER_ENABLED is explicitly false.
27
  // HUGGINGCLAW_JUPYTER_ENABLED=true is the explicit user override and always wins.
28
  const JUPYTER_ENABLED =
29
  /^(true|1|yes|on)$/i.test(String(process.env.HUGGINGCLAW_JUPYTER_ENABLED || "").trim()) ||
30
  (
31
+ isTrue(process.env.DEV_MODE) &&
32
  !/^(false|0|no|off)$/i.test(String(process.env.HUGGINGCLAW_JUPYTER_ENABLED || "").trim())
33
  );
34
  const startTime = Date.now();
 
253
 
254
  // Constant-time comparison β€” prevent timing attacks on token check
255
  function safeEqual(a, b) {
256
+ if (typeof a !== "string" || typeof b !== "string") return false;
257
+ // Pad both to the same length so the loop always takes constant time,
258
+ // preventing token length from being leaked via early-return timing.
259
+ const len = Math.max(a.length, b.length, 1);
260
+ const pa = a.padEnd(len, "\0");
261
+ const pb = b.padEnd(len, "\0");
262
+ let d = a.length === b.length ? 0 : 1; // length mismatch β†’ always fail
263
+ for (let i = 0; i < len; i++) d |= pa.charCodeAt(i) ^ pb.charCodeAt(i);
264
  return d === 0;
265
  }
266
 
 
674
  const body = await readBody(req);
675
  const token = decodeURIComponent((body.match(/(?:^|&)token=([^&]*)/) || [])[1] || "").replace(/\+/g, " ");
676
  if (safeEqual(token, GATEWAY_TOKEN)) {
677
+ const cookie = `hc_env_auth=${encodeURIComponent(GATEWAY_TOKEN)}; Path=/; HttpOnly; SameSite=None; Secure; Max-Age=86400`;
678
  res.writeHead(302, { Location: "/env-builder", "Set-Cookie": cookie, "Cache-Control": "no-store" });
679
  return res.end();
680
  }
 
686
  }
687
 
688
  if (pathname === "/env-builder/logout") {
689
+ res.writeHead(302, { Location: "/env-builder", "Set-Cookie": "hc_env_auth=; Path=/; HttpOnly; SameSite=None; Secure; Max-Age=0", "Cache-Control": "no-store" });
690
  return res.end();
691
  }
692
 
multi-provider-key-rotator.cjs CHANGED
@@ -86,6 +86,13 @@ const PROVIDERS = [
86
  envPlural: 'ZAI_API_KEYS',
87
  envSingular:'ZAI_API_KEY',
88
  },
 
 
 
 
 
 
 
89
  {
90
  name: 'moonshot',
91
  hostname: /(?:^|\.)api\.moonshot\.cn$/i,
 
86
  envPlural: 'ZAI_API_KEYS',
87
  envSingular:'ZAI_API_KEY',
88
  },
89
+ {
90
+ name: 'kimi-coding',
91
+ // kimi-coding routes through api.moonshot.cn; dedicated entry so KIMI_API_KEYS pool is used
92
+ hostname: /(?:^|\.)api\.moonshot\.cn$/i,
93
+ envPlural: 'KIMI_API_KEYS',
94
+ envSingular:'KIMI_API_KEY',
95
+ },
96
  {
97
  name: 'moonshot',
98
  hostname: /(?:^|\.)api\.moonshot\.cn$/i,
start.sh CHANGED
@@ -203,7 +203,7 @@ case "$LLM_PROVIDER" in
203
  byteplus|byteplus-plan) export BYTEPLUS_API_KEY="$LLM_API_KEY" ;;
204
  qianfan) export QIANFAN_API_KEY="$LLM_API_KEY" ;;
205
  # ── Western Providers ──
206
- mistral|mistralai) export MISTRAL_API_KEY="$LLM_API_KEY" ;;
207
  xai|x-ai) export XAI_API_KEY="$LLM_API_KEY" ;;
208
  nvidia) export NVIDIA_API_KEY="$LLM_API_KEY" ;;
209
  cohere) export COHERE_API_KEY="$LLM_API_KEY" ;;
@@ -1772,16 +1772,6 @@ while true; do
1772
  # 11. Start WhatsApp Guardian after the gateway is accepting connections
1773
  start_guardian_once
1774
 
1775
- # ── Silence D-Bus errors for headless Chromium ──
1776
- if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
1777
- if command -v dbus-launch >/dev/null 2>&1; then
1778
- eval "$(dbus-launch --sh-syntax 2>/dev/null)" || true
1779
- export DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-disabled:}"
1780
- else
1781
- export DBUS_SESSION_BUS_ADDRESS="disabled:"
1782
- fi
1783
- fi
1784
-
1785
  # 11.5 Warm up the managed browser so first browser actions have a live tab
1786
  warmup_browser
1787
 
 
203
  byteplus|byteplus-plan) export BYTEPLUS_API_KEY="$LLM_API_KEY" ;;
204
  qianfan) export QIANFAN_API_KEY="$LLM_API_KEY" ;;
205
  # ── Western Providers ──
206
+ mistral) export MISTRAL_API_KEY="$LLM_API_KEY" ;;
207
  xai|x-ai) export XAI_API_KEY="$LLM_API_KEY" ;;
208
  nvidia) export NVIDIA_API_KEY="$LLM_API_KEY" ;;
209
  cohere) export COHERE_API_KEY="$LLM_API_KEY" ;;
 
1772
  # 11. Start WhatsApp Guardian after the gateway is accepting connections
1773
  start_guardian_once
1774
 
 
 
 
 
 
 
 
 
 
 
1775
  # 11.5 Warm up the managed browser so first browser actions have a live tab
1776
  warmup_browser
1777