From f05f175842d57003692ea766b07857d6f4b05f2b Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Tue, 13 Jan 2026 13:58:00 +0800 Subject: feat(desktop): spawn local server with password (#8139) --- packages/desktop/src/index.tsx | 54 ++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'packages/desktop/src') diff --git a/packages/desktop/src/index.tsx b/packages/desktop/src/index.tsx index a26cc61ca..1ad015aff 100644 --- a/packages/desktop/src/index.tsx +++ b/packages/desktop/src/index.tsx @@ -13,12 +13,11 @@ import { AsyncStorage } from "@solid-primitives/storage" import { fetch as tauriFetch } from "@tauri-apps/plugin-http" import { Store } from "@tauri-apps/plugin-store" import { Logo } from "@opencode-ai/ui/logo" -import { Accessor, JSX, createResource } from "solid-js" +import { createSignal, Show, Accessor, JSX, createResource } from "solid-js" import { UPDATER_ENABLED } from "./updater" import { createMenu } from "./menu" import pkg from "../package.json" -import { Show } from "solid-js" const root = document.getElementById("root") if (import.meta.env.DEV && !(root instanceof HTMLElement)) { @@ -29,7 +28,7 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) { let update: Update | null = null -const platform: Platform = { +const createPlatform = (password: Accessor): Platform => ({ platform: "desktop", version: pkg.version, @@ -256,7 +255,25 @@ const platform: Platform = { }, // @ts-expect-error - fetch: tauriFetch, + fetch: (input, init) => { + const pw = password() + + const addHeader = (headers: Headers, password: string) => { + headers.append("Authorization", `Basic ${btoa(`opencode:${password}`)}`) + } + + if (input instanceof Request) { + if (pw) addHeader(input.headers, pw) + return tauriFetch(input) + } else { + const headers = new Headers(init?.headers) + if (pw) addHeader(headers, pw) + return tauriFetch(input, { + ...(init as any), + headers: headers, + }) + } + }, getDefaultServerUrl: async () => { const result = await invoke("get_default_server_url").catch(() => null) @@ -266,7 +283,7 @@ const platform: Platform = { setDefaultServerUrl: async (url: string | null) => { await invoke("set_default_server_url", { url }) }, -} +}) createMenu() @@ -276,26 +293,37 @@ root?.addEventListener("mousewheel", (e) => { }) render(() => { + const [serverPassword, setServerPassword] = createSignal(null) + const platform = createPlatform(() => serverPassword()) + return ( - {ostype() === "macos" && ( -
- )} - {(serverUrl) => } + {ostype() === "macos" && ( +
+ )} + + {(data) => { + setServerPassword(data().password) + + return + }} + ) }, root!) +type ServerReadyData = { url: string; password: string | null } + // Gate component that waits for the server to be ready -function ServerGate(props: { children: (url: Accessor) => JSX.Element }) { - const [serverUrl] = createResource(() => invoke("ensure_server_ready")) +function ServerGate(props: { children: (data: Accessor) => JSX.Element }) { + const [serverData] = createResource(() => invoke("ensure_server_ready")) return ( // Not using suspense as not all components are compatible with it (undefined refs) @@ -303,7 +331,7 @@ function ServerGate(props: { children: (url: Accessor) => JSX.Element })
} > - {(serverUrl) => props.children(serverUrl)} + {(data) => props.children(data)} ) } -- cgit v1.2.3