Archived
feat: add external path access allowlist
This commit is contained in:
+18
-10
@@ -7,7 +7,8 @@ import fastifyWebsocket from "@fastify/websocket";
|
||||
import { ProjectStore } from "./storage/projectStore.js";
|
||||
import { ProjectService } from "./projects/projectService.js";
|
||||
import { WorkspaceService } from "./workspaces/workspaceService.js";
|
||||
import { listFileSuggestions, listPathSuggestions } from "./workspaces/fileSuggestions.js";
|
||||
import { isAbsoluteishFileSuggestionQuery, listFileSuggestions, listPathSuggestions } from "./workspaces/fileSuggestions.js";
|
||||
import { pathAccessForCwd } from "./workspaces/effectivePathAccess.js";
|
||||
import { normalizeRequestCwd } from "./workingDirectory.js";
|
||||
import { listDirectorySuggestions } from "./projects/directorySuggestions.js";
|
||||
import { SessionDaemonClient } from "../sessiond/sessionDaemonClient.js";
|
||||
@@ -16,7 +17,7 @@ import { registerWorkspaceExplorerRoutes } from "./workspaceExplorerRoutes.js";
|
||||
import { registerGitRoutes } from "./gitRoutes.js";
|
||||
import { registerTerminalProxyRoutes } from "./terminalProxyRoutes.js";
|
||||
import { registerWorkspaceDeletionRoutes } from "./workspaces/workspaceDeletionRoutes.js";
|
||||
import { registerConfigRoutes, type PiWebConfigService } from "./configRoutes.js";
|
||||
import { createFilePiWebConfigService, registerConfigRoutes, type PiWebConfigService } from "./configRoutes.js";
|
||||
import { PiWebPluginService } from "./piWebPluginService.js";
|
||||
import { createPiWebStatusCache } from "./piWebStatusCache.js";
|
||||
import { getPiWebRuntime, getPiWebStatus, getPiWebVersionStatus } from "./piWebStatus.js";
|
||||
@@ -76,13 +77,19 @@ function registerLocalProjectRoutes(app: FastifyInstance, projects: ProjectServi
|
||||
});
|
||||
}
|
||||
|
||||
function registerLocalFileSuggestionRoutes(app: FastifyInstance, prefix: string): void {
|
||||
interface LocalFileSuggestionRouteOptions {
|
||||
config?: Pick<PiWebConfigService, "read">;
|
||||
}
|
||||
|
||||
function registerLocalFileSuggestionRoutes(app: FastifyInstance, projects: ProjectService, workspaces: WorkspaceService, prefix: string, options: LocalFileSuggestionRouteOptions = {}): void {
|
||||
app.get<{ Querystring: { cwd?: string; q?: string; kind?: "tracked" | "untracked" | "other"; mode?: "file" | "path"; scope?: "tracked" | "all" } }>(`${prefix}/files`, async (request, reply) => {
|
||||
if (request.query.cwd === undefined || request.query.cwd === "") return reply.code(400).send({ error: "cwd query parameter is required" });
|
||||
try {
|
||||
const cwd = normalizeRequestCwd(request.query.cwd);
|
||||
if (request.query.mode === "path") return await listPathSuggestions(cwd, request.query.q ?? "");
|
||||
return await listFileSuggestions(cwd, request.query.q ?? "", { kind: request.query.kind, scope: request.query.scope });
|
||||
const query = request.query.q ?? "";
|
||||
const pathAccess = isAbsoluteishFileSuggestionQuery(query) ? await pathAccessForCwd(cwd, projects, workspaces, options.config) : undefined;
|
||||
if (request.query.mode === "path") return await listPathSuggestions(cwd, query, pathAccess);
|
||||
return await listFileSuggestions(cwd, query, { kind: request.query.kind, scope: request.query.scope, pathAccess });
|
||||
} catch (error) {
|
||||
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
||||
}
|
||||
@@ -96,6 +103,7 @@ export async function buildApp(deps: AppDependencies = {}): Promise<FastifyInsta
|
||||
const projects = deps.projects ?? new ProjectService(new ProjectStore());
|
||||
const workspaces = deps.workspaces ?? new WorkspaceService();
|
||||
const piWebPlugins = deps.piWebPlugins ?? new PiWebPluginService();
|
||||
const configService = deps.config ?? createFilePiWebConfigService();
|
||||
const sessionDaemon = deps.sessionDaemon ?? new SessionDaemonClient();
|
||||
const piWebStatusCache = createPiWebStatusCache(() => getPiWebStatus(sessionDaemon), {
|
||||
onError: (error) => { app.log.warn({ err: error }, "failed to refresh PI WEB status cache"); },
|
||||
@@ -118,7 +126,7 @@ export async function buildApp(deps: AppDependencies = {}): Promise<FastifyInsta
|
||||
app.get("/api/pi-web/version", async () => getPiWebVersionStatus(sessionDaemon));
|
||||
app.get("/api/pi-web/runtime", async () => getPiWebRuntime(sessionDaemon));
|
||||
app.get("/api/plugins", async () => piWebPlugins.plugins());
|
||||
registerConfigRoutes(app, deps.config);
|
||||
registerConfigRoutes(app, configService);
|
||||
|
||||
registerMachineRoutes(app, machines);
|
||||
registerMachinePluginProxyRoutes(app, machines);
|
||||
@@ -128,8 +136,8 @@ export async function buildApp(deps: AppDependencies = {}): Promise<FastifyInsta
|
||||
|
||||
registerSessionProxyRoutes(app, sessionDaemon);
|
||||
registerSessionProxyRoutes(app, sessionDaemon, "/api/machines/local");
|
||||
registerWorkspaceExplorerRoutes(app, projects, workspaces);
|
||||
registerWorkspaceExplorerRoutes(app, projects, workspaces, "/api/machines/local");
|
||||
registerWorkspaceExplorerRoutes(app, projects, workspaces, "/api", { config: configService });
|
||||
registerWorkspaceExplorerRoutes(app, projects, workspaces, "/api/machines/local", { config: configService });
|
||||
registerGitRoutes(app, projects, workspaces);
|
||||
registerGitRoutes(app, projects, workspaces, "/api/machines/local");
|
||||
registerTerminalProxyRoutes(app, projects, workspaces, sessionDaemon);
|
||||
@@ -137,8 +145,8 @@ export async function buildApp(deps: AppDependencies = {}): Promise<FastifyInsta
|
||||
registerWorkspaceDeletionRoutes(app, projects, workspaces, sessionDaemon);
|
||||
registerWorkspaceDeletionRoutes(app, projects, workspaces, sessionDaemon, "/api/machines/local");
|
||||
|
||||
registerLocalFileSuggestionRoutes(app, "/api");
|
||||
registerLocalFileSuggestionRoutes(app, "/api/machines/local");
|
||||
registerLocalFileSuggestionRoutes(app, projects, workspaces, "/api", { config: configService });
|
||||
registerLocalFileSuggestionRoutes(app, projects, workspaces, "/api/machines/local", { config: configService });
|
||||
|
||||
registerMachineProxyRoutes(app, machines);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user