mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
6ea364e67d
Add token-based authentication for the Launcher's embedded Web Dashboard. - Ephemeral token generated in-memory each run (or via PICOCLAW_LAUNCHER_TOKEN env var) - HMAC-SHA256 session cookie (HttpOnly, SameSite=Lax, Secure when HTTPS) - Bearer token support for API/script access - Rate limiting on login (10 attempts/IP/min) - Referrer-Policy: no-referrer on all responses - POST-only logout with JSON content-type (CSRF-safe) - System tray "Copy dashboard token" action - Login page shows contextual help (console/tray/log file path) - Path traversal protection via path.Clean - X-Forwarded-Host/Port/Proto support for reverse proxy deployments - Full i18n support (English, Chinese) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
import { isLauncherLoginPathname } from "@/lib/launcher-login-path"
|
|
|
|
function isLauncherLoginPath(): boolean {
|
|
if (typeof globalThis.location === "undefined") {
|
|
return false
|
|
}
|
|
if (isLauncherLoginPathname(globalThis.location.pathname || "/")) {
|
|
return true
|
|
}
|
|
try {
|
|
return isLauncherLoginPathname(
|
|
new URL(globalThis.location.href).pathname || "/",
|
|
)
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Same-origin fetch that sends cookies; redirects to launcher login on 401 JSON responses.
|
|
* Skips redirect while already on the login page to avoid reload loops (e.g. gateway poll).
|
|
*/
|
|
export async function launcherFetch(
|
|
input: RequestInfo | URL,
|
|
init?: RequestInit,
|
|
): Promise<Response> {
|
|
const res = await fetch(input, {
|
|
credentials: "same-origin",
|
|
...init,
|
|
})
|
|
if (res.status === 401) {
|
|
const ct = res.headers.get("content-type") || ""
|
|
if (
|
|
ct.includes("application/json") &&
|
|
typeof globalThis.location !== "undefined" &&
|
|
!isLauncherLoginPath()
|
|
) {
|
|
globalThis.location.assign("/launcher-login")
|
|
}
|
|
}
|
|
return res
|
|
}
|