mirror of
https://github.com/andrewyng/openworker.git
synced 2026-09-11 06:30:25 +00:00
security: complete local access protections
This commit is contained in:
@@ -2,11 +2,11 @@
|
||||
// /v1/providers to catch integration drift between the GUI's expectations and the backend's
|
||||
// responses. Skips cleanly when the backend is down, so it's safe to run anytime. No creds needed.
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { BACKEND } from "./helpers";
|
||||
import { backendFetch } from "./helpers";
|
||||
|
||||
async function backendUp(): Promise<boolean> {
|
||||
try {
|
||||
const res = await fetch(`${BACKEND}/v1/health`);
|
||||
const res = await backendFetch("/v1/health");
|
||||
return res.ok;
|
||||
} catch {
|
||||
return false;
|
||||
@@ -15,7 +15,7 @@ async function backendUp(): Promise<boolean> {
|
||||
|
||||
test("health reports ok with the fields the GUI reads", async () => {
|
||||
test.skip(!(await backendUp()), "backend not running on :8765");
|
||||
const s = await (await fetch(`${BACKEND}/v1/health`)).json();
|
||||
const s = await (await backendFetch("/v1/health")).json();
|
||||
expect(s.status).toBe("ok");
|
||||
// The GUI's boot reads these three off /v1/health.
|
||||
expect(s).toHaveProperty("model");
|
||||
@@ -24,7 +24,7 @@ test("health reports ok with the fields the GUI reads", async () => {
|
||||
|
||||
test("providers list has the shape the Settings pane expects", async () => {
|
||||
test.skip(!(await backendUp()), "backend not running on :8765");
|
||||
const providers = await (await fetch(`${BACKEND}/v1/providers`)).json();
|
||||
const providers = await (await backendFetch("/v1/providers")).json();
|
||||
expect(Array.isArray(providers)).toBe(true);
|
||||
expect(providers.length).toBeGreaterThan(0);
|
||||
// Each descriptor carries what ManageTabs renders: name/title/needs_key/fields/configured.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { readdirSync, statSync } from "fs";
|
||||
import { readFileSync, readdirSync, statSync } from "fs";
|
||||
import { homedir } from "os";
|
||||
import { join } from "path";
|
||||
import type { Page } from "@playwright/test";
|
||||
@@ -8,10 +8,31 @@ import type { Page } from "@playwright/test";
|
||||
|
||||
export const BACKEND = "http://127.0.0.1:8765";
|
||||
|
||||
function sidecarToken(): string {
|
||||
const state =
|
||||
process.env.COWORKER_STATE_DIR ||
|
||||
(process.platform === "win32"
|
||||
? join(process.env.APPDATA || homedir(), "coworker")
|
||||
: join(homedir(), ".config", "coworker"));
|
||||
try {
|
||||
return readFileSync(join(state, "sidecar-8765.token"), "utf8").trim();
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/** Fetch from the live sidecar with its per-launch authentication token. */
|
||||
export function backendFetch(path: string, init: RequestInit = {}): Promise<Response> {
|
||||
const headers = new Headers(init.headers);
|
||||
const token = sidecarToken();
|
||||
if (token) headers.set("X-OpenWorker-Token", token);
|
||||
return fetch(`${BACKEND}${path}`, { ...init, headers });
|
||||
}
|
||||
|
||||
/** The expanded scratch base if the backend is up and a model is ready — else null (→ skip). */
|
||||
export async function scratchBaseIfReady(): Promise<string | null> {
|
||||
try {
|
||||
const res = await fetch(`${BACKEND}/v1/settings`);
|
||||
const res = await backendFetch("/v1/settings");
|
||||
const s = await res.json();
|
||||
if (res.ok && s.model_ready) {
|
||||
return String(s.scratch_base || "~/OpenWorker").replace(/^~(?=\/|$)/, homedir());
|
||||
|
||||
Reference in New Issue
Block a user