Spaces:
Build error
Build error
tao-shen Claude Opus 4.6 commited on
Commit ·
7b4c5b7
1
Parent(s): 3925157
fix: use global variable for token injection (works in incognito iframe)
Browse filesWhen HF Spaces embeds the Control UI in an iframe, Chrome incognito
blocks third-party localStorage access. The token injection via
localStorage silently fails, leaving the UI unable to authenticate.
Changes:
- Add source patch: storage.ts reads window.__OPENCLAW_AUTH_TOKEN__
as fallback when localStorage token is empty/unavailable
- inject-token.sh: set window.__OPENCLAW_AUTH_TOKEN__ global variable
in addition to localStorage (global always works)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
patches/hf-spaces-global-token-fallback.patch
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
diff --git a/ui/src/ui/storage.ts b/ui/src/ui/storage.ts
|
| 2 |
+
index b32e6c3..763a543 100644
|
| 3 |
+
--- a/ui/src/ui/storage.ts
|
| 4 |
+
+++ b/ui/src/ui/storage.ts
|
| 5 |
+
@@ -17,6 +17,14 @@ export type UiSettings = {
|
| 6 |
+
locale?: string;
|
| 7 |
+
};
|
| 8 |
+
|
| 9 |
+
+// Read an injected auth token from a global variable.
|
| 10 |
+
+// Used by HF Spaces where localStorage may be unavailable
|
| 11 |
+
+// (e.g. third-party iframe in incognito mode).
|
| 12 |
+
+function getInjectedToken(): string {
|
| 13 |
+
+ const w = globalThis as Record<string, unknown>;
|
| 14 |
+
+ return typeof w.__OPENCLAW_AUTH_TOKEN__ === "string" ? (w.__OPENCLAW_AUTH_TOKEN__ as string) : "";
|
| 15 |
+
+}
|
| 16 |
+
+
|
| 17 |
+
export function loadSettings(): UiSettings {
|
| 18 |
+
const defaultUrl = (() => {
|
| 19 |
+
const proto = location.protocol === "https:" ? "wss" : "ws";
|
| 20 |
+
@@ -25,7 +33,7 @@ export function loadSettings(): UiSettings {
|
| 21 |
+
|
| 22 |
+
const defaults: UiSettings = {
|
| 23 |
+
gatewayUrl: defaultUrl,
|
| 24 |
+
- token: "",
|
| 25 |
+
+ token: getInjectedToken(),
|
| 26 |
+
sessionKey: "main",
|
| 27 |
+
lastActiveSessionKey: "main",
|
| 28 |
+
theme: "system",
|
| 29 |
+
@@ -47,7 +55,7 @@ export function loadSettings(): UiSettings {
|
| 30 |
+
typeof parsed.gatewayUrl === "string" && parsed.gatewayUrl.trim()
|
| 31 |
+
? parsed.gatewayUrl.trim()
|
| 32 |
+
: defaults.gatewayUrl,
|
| 33 |
+
- token: typeof parsed.token === "string" ? parsed.token : defaults.token,
|
| 34 |
+
+ token: typeof parsed.token === "string" && parsed.token ? parsed.token : defaults.token,
|
| 35 |
+
sessionKey:
|
| 36 |
+
typeof parsed.sessionKey === "string" && parsed.sessionKey.trim()
|
| 37 |
+
? parsed.sessionKey.trim()
|
scripts/inject-token.sh
CHANGED
|
@@ -11,7 +11,9 @@ if [ ! -f "$INDEX_HTML" ]; then
|
|
| 11 |
fi
|
| 12 |
|
| 13 |
# Create the injection script
|
| 14 |
-
|
|
|
|
|
|
|
| 15 |
|
| 16 |
# Use python3 for reliable string replacement (avoids sed delimiter issues)
|
| 17 |
python3 -c "
|
|
@@ -20,7 +22,7 @@ f = '${INDEX_HTML}'
|
|
| 20 |
with open(f, 'r') as fh:
|
| 21 |
html = fh.read()
|
| 22 |
inject = '''${INJECT_SCRIPT}'''
|
| 23 |
-
if '</head>' in html and
|
| 24 |
html = html.replace('</head>', inject + '</head>')
|
| 25 |
with open(f, 'w') as fh:
|
| 26 |
fh.write(html)
|
|
|
|
| 11 |
fi
|
| 12 |
|
| 13 |
# Create the injection script
|
| 14 |
+
# 1. Set window.__OPENCLAW_AUTH_TOKEN__ — always works (even when localStorage is blocked in iframe/incognito)
|
| 15 |
+
# 2. Also try localStorage as a fallback for the original UI code path
|
| 16 |
+
INJECT_SCRIPT="<script>window.__OPENCLAW_AUTH_TOKEN__='${TOKEN}';try{var K='openclaw.control.settings.v1',s=JSON.parse(localStorage.getItem(K)||'{}');s.token='${TOKEN}';localStorage.setItem(K,JSON.stringify(s))}catch(e){}</script>"
|
| 17 |
|
| 18 |
# Use python3 for reliable string replacement (avoids sed delimiter issues)
|
| 19 |
python3 -c "
|
|
|
|
| 22 |
with open(f, 'r') as fh:
|
| 23 |
html = fh.read()
|
| 24 |
inject = '''${INJECT_SCRIPT}'''
|
| 25 |
+
if '</head>' in html and '__OPENCLAW_AUTH_TOKEN__' not in html:
|
| 26 |
html = html.replace('</head>', inject + '</head>')
|
| 27 |
with open(f, 'w') as fh:
|
| 28 |
fh.write(html)
|