refactor(web): secure Pico websocket access behind launcher auth

- stop exposing the raw Pico token to the frontend
- add /api/pico/info for non-secret Pico connection metadata
- proxy /pico/ws through the launcher with same-origin and dashboard auth checks
- inject the upstream Pico websocket protocol server-side
- update frontend chat connection flow and Vite websocket proxy path
- refresh related docs and tests
This commit is contained in:
wenjie
2026-04-16 16:47:23 +08:00
parent 6126ede963
commit 4b76196e2c
14 changed files with 253 additions and 171 deletions
+8 -8
View File
@@ -2,16 +2,16 @@ import { launcherFetch } from "@/api/http"
// API client for Pico Channel configuration.
interface PicoTokenResponse {
token: string
interface PicoInfoResponse {
ws_url: string
enabled: boolean
configured?: boolean
}
interface PicoSetupResponse {
token: string
ws_url: string
enabled: boolean
configured?: boolean
changed: boolean
}
@@ -25,16 +25,16 @@ async function request<T>(path: string, options?: RequestInit): Promise<T> {
return res.json() as Promise<T>
}
export async function getPicoToken(): Promise<PicoTokenResponse> {
return request<PicoTokenResponse>("/api/pico/token")
export async function getPicoInfo(): Promise<PicoInfoResponse> {
return request<PicoInfoResponse>("/api/pico/info")
}
export async function regenPicoToken(): Promise<PicoTokenResponse> {
return request<PicoTokenResponse>("/api/pico/token", { method: "POST" })
export async function regenPicoToken(): Promise<PicoInfoResponse> {
return request<PicoInfoResponse>("/api/pico/token", { method: "POST" })
}
export async function setupPico(): Promise<PicoSetupResponse> {
return request<PicoSetupResponse>("/api/pico/setup", { method: "POST" })
}
export type { PicoTokenResponse, PicoSetupResponse }
export type { PicoInfoResponse, PicoSetupResponse }