Files
pikasTech-HWLAB/internal/dev-entrypoint/cloud-web-routes.mjs
T

157 lines
6.8 KiB
JavaScript

const GET_PROXY_PREFIXES = Object.freeze(["/v1/"]);
const GET_PROXY_ROUTES = new Set(["/v1", "/auth/session", "/auth/bootstrap"]);
const POST_PROXY_ROUTES = new Set([
"/auth/login",
"/auth/register",
"/auth/logout",
"/v1/agent/chat",
"/v1/agent/chat/cancel",
"/v1/agent/chat/steer",
"/v1/agent/sessions",
"/v1/workbench/commands",
"/v1/workbench/launches",
"/v1/hwpod-node-ops",
"/v1/web-performance",
"/v1/m3/io",
"/v1/skills/uploads"
]);
const PUBLIC_PROXY_ROUTES = new Set([
"GET /auth/session",
"GET /auth/bootstrap",
"POST /auth/login",
"POST /auth/register",
"POST /auth/logout",
"POST /v1/agent/chat",
"POST /v1/agent/chat/cancel",
"POST /v1/agent/chat/steer",
"POST /v1/web-performance"
]);
export function cloudWebProxyRoutePolicy(method, pathname) {
const normalizedMethod = normalizeMethod(method);
const normalizedPath = normalizePathname(pathname);
const routeKey = `${normalizedMethod} ${normalizedPath}`;
const proxy = isCloudApiProxyRoute(normalizedMethod, normalizedPath);
const publicRoute = proxy && (
PUBLIC_PROXY_ROUTES.has(routeKey) ||
isPublicCodeAgentPollRoute(normalizedMethod, normalizedPath)
);
return {
proxy,
authRequired: proxy && !publicRoute,
publicRoute,
routeKey
};
}
export function isCloudApiProxyRoute(method, pathname) {
const normalizedMethod = normalizeMethod(method);
const normalizedPath = normalizePathname(pathname);
if (normalizedMethod === "GET") {
return GET_PROXY_ROUTES.has(normalizedPath) ||
GET_PROXY_PREFIXES.some((prefix) => normalizedPath.startsWith(prefix));
}
if (normalizedMethod === "POST") {
return POST_PROXY_ROUTES.has(normalizedPath) ||
isCaseRunWriteProxyRoute(normalizedMethod, normalizedPath) ||
isAdminAccessWriteProxyRoute(normalizedMethod, normalizedPath) ||
isProviderProfileManagementProxyRoute(normalizedMethod, normalizedPath) ||
isProjectManagementWriteProxyRoute(normalizedMethod, normalizedPath) ||
isApiKeyWriteProxyRoute(normalizedMethod, normalizedPath) ||
isAdminBillingWriteProxyRoute(normalizedMethod, normalizedPath) ||
normalizedPath.startsWith("/v1/rpc/") ||
normalizedPath.startsWith("/v1/agent/sessions/");
}
if (normalizedMethod === "PATCH" || normalizedMethod === "PUT") {
return isAdminAccessWriteProxyRoute(normalizedMethod, normalizedPath) ||
isAdminBillingWriteProxyRoute(normalizedMethod, normalizedPath) ||
isProviderProfileManagementProxyRoute(normalizedMethod, normalizedPath) ||
isProjectManagementWriteProxyRoute(normalizedMethod, normalizedPath) ||
isApiKeyWriteProxyRoute(normalizedMethod, normalizedPath);
}
if (normalizedMethod === "DELETE") {
return isAdminAccessWriteProxyRoute(normalizedMethod, normalizedPath) ||
isProviderProfileManagementProxyRoute(normalizedMethod, normalizedPath) ||
isProjectManagementWriteProxyRoute(normalizedMethod, normalizedPath) ||
isApiKeyWriteProxyRoute(normalizedMethod, normalizedPath);
}
return false;
}
function isCaseRunWriteProxyRoute(method, pathname) {
if (method !== "POST") return false;
if (pathname === "/v1/caserun/runs") return true;
const parts = pathname.split("/").filter(Boolean);
return parts.length === 5 && parts[0] === "v1" && parts[1] === "caserun" && parts[2] === "runs" && parts[4] === "cancel";
}
function isAdminAccessWriteProxyRoute(method, pathname) {
if (method === "POST" && pathname === "/v1/admin/access/check") return true;
const parts = pathname.split("/").filter(Boolean);
if (parts.length < 5 || parts[0] !== "v1" || parts[1] !== "admin" || parts[2] !== "access" || parts[3] !== "users") return false;
if (method === "PATCH" && parts.length === 5) return true;
if ((method === "PUT" || method === "DELETE") && parts.length === 8 && parts[5] === "tools" && parts[7] === "can-use") return true;
return false;
}
function isProviderProfileManagementProxyRoute(method, pathname) {
const parts = pathname.split("/").filter(Boolean);
if (parts.length < 4 || parts[0] !== "v1" || parts[1] !== "admin" || parts[2] !== "provider-profiles") return false;
if (method === "DELETE" && parts.length === 4) return true;
if (method === "PUT" && parts.length === 5 && parts[4] === "credential") return true;
if (method === "PUT" && parts.length === 5 && parts[4] === "config") return true;
if (method === "POST" && parts.length === 5 && parts[4] === "validate") return true;
if (method === "POST" && parts.length === 5 && parts[4] === "test") return true;
return false;
}
function isApiKeyWriteProxyRoute(method, pathname) {
if (pathname === "/v1/api-keys" && method === "POST") return true;
if (!pathname.startsWith("/v1/api-keys/")) return false;
if (method === "PATCH") return true;
if (method === "DELETE") return true;
if (method !== "POST") return false;
return pathname.endsWith("/regenerate");
}
function isAdminBillingWriteProxyRoute(method, pathname) {
const parts = pathname.split("/").filter(Boolean);
if (parts.length < 4 || parts[0] !== "v1" || parts[1] !== "admin" || parts[2] !== "billing" || parts[3] !== "users") return false;
if (method === "POST" && parts.length === 4) return true;
if (method === "PATCH" && parts.length === 5) return true;
if (method === "PATCH" && parts.length === 6 && parts[5] === "status") return true;
if (method === "POST" && parts.length === 7 && parts[5] === "credits" && parts[6] === "adjust") return true;
return false;
}
function isProjectManagementWriteProxyRoute(method, pathname) {
if (method === "POST" && pathname === "/v1/project-management/workbench-links") return true;
if (method === "POST" && pathname === "/v1/project-management/mdtodo/sources") return true;
if ((method === "PATCH" || method === "DELETE") && /^\/v1\/project-management\/mdtodo\/sources\/[^/]+$/u.test(pathname)) return true;
if (method === "POST" && /^\/v1\/project-management\/mdtodo\/sources\/[^/]+\/(?:probe|reindex)$/u.test(pathname)) return true;
if (method === "PATCH" && /^\/v1\/project-management\/mdtodo\/files\/[^/]+\/content$/u.test(pathname)) return true;
if (method === "POST" && pathname === "/v1/project-management/mdtodo/tasks") return true;
if ((method === "PATCH" || method === "DELETE") && /^\/v1\/project-management\/mdtodo\/tasks\/[^/]+$/u.test(pathname)) return true;
return false;
}
function isPublicCodeAgentPollRoute(method, pathname) {
return method === "GET" && (
pathname.startsWith("/v1/agent/turns/") ||
pathname.startsWith("/v1/agent/chat/result/") ||
pathname.startsWith("/v1/agent/traces/")
);
}
function normalizeMethod(method) {
return String(method || "GET").trim().toUpperCase() || "GET";
}
function normalizePathname(pathname) {
const value = String(pathname || "/").trim();
if (!value || value[0] !== "/") return "/";
return value.replace(/\/+$/u, "") || "/";
}