diff --git a/internal/dev-entrypoint/cloud-web-routes.mjs b/internal/dev-entrypoint/cloud-web-routes.mjs index da9fa6ec..49f8a067 100644 --- a/internal/dev-entrypoint/cloud-web-routes.mjs +++ b/internal/dev-entrypoint/cloud-web-routes.mjs @@ -1,5 +1,5 @@ const GET_PROXY_PREFIXES = Object.freeze(["/v1/"]); -const GET_PROXY_ROUTES = new Set(["/v1", "/auth/session", "/auth/bootstrap", "/auth/workspace-bootstrap"]); +const GET_PROXY_ROUTES = new Set(["/v1", "/auth/session", "/auth/bootstrap"]); const POST_PROXY_ROUTES = new Set([ "/auth/login", "/auth/register", @@ -17,7 +17,6 @@ const POST_PROXY_ROUTES = new Set([ const PUBLIC_PROXY_ROUTES = new Set([ "GET /auth/session", "GET /auth/bootstrap", - "GET /auth/workspace-bootstrap", "POST /auth/login", "POST /auth/register", "POST /auth/logout", diff --git a/internal/dev-entrypoint/cloud-web-routes.test.mjs b/internal/dev-entrypoint/cloud-web-routes.test.mjs index c48fc867..f8163481 100644 --- a/internal/dev-entrypoint/cloud-web-routes.test.mjs +++ b/internal/dev-entrypoint/cloud-web-routes.test.mjs @@ -61,12 +61,6 @@ test("cloud web exposes auth bootstrap as a public auth route", () => { publicRoute: true, routeKey: "GET /auth/bootstrap" }); - assert.deepEqual(cloudWebProxyRoutePolicy("GET", "/auth/workspace-bootstrap"), { - proxy: true, - authRequired: false, - publicRoute: true, - routeKey: "GET /auth/workspace-bootstrap" - }); assert.deepEqual(cloudWebProxyRoutePolicy("POST", "/auth/register"), { proxy: true, authRequired: false, diff --git a/internal/dev-entrypoint/cloud-web-runtime.mjs b/internal/dev-entrypoint/cloud-web-runtime.mjs index d8bfa32a..5d0c3b4a 100644 --- a/internal/dev-entrypoint/cloud-web-runtime.mjs +++ b/internal/dev-entrypoint/cloud-web-runtime.mjs @@ -15,7 +15,6 @@ const readOnlyRpcMethods = new Set([ ]); const gzipAsync = promisify(gzip); const GZIP_MIN_BYTES = 1024; -const DEFAULT_WORKBENCH_PROJECT_ID = "prj_hwpod_workbench"; const CLIENT_DISCONNECT_ERROR_CODES = new Set([ "ECONNRESET", "EPIPE", @@ -191,10 +190,6 @@ function logCloudWebRuntimeEvent(event, { serviceId, request = null, error = nul export async function handleCloudWebAuth(options) { const { request, response, url } = options; - if (url.pathname === "/auth/workspace-bootstrap" && request.method === "GET") { - await handleWorkspaceBootstrap(options); - return true; - } if (url.pathname === "/auth/bootstrap" && request.method === "GET") { await handleAuthBootstrap(options); return true; @@ -231,47 +226,11 @@ async function handleAuthBootstrap(options) { sendJsonWithForwardedCookies(response, auth.statusCode || 502, auth.body ?? { authenticated: false, error: "auth_bootstrap_failed" }, auth.headers); } -async function handleWorkspaceBootstrap(options) { - const { request, response, url, cloudApiBaseUrl, cloudApiProxyTimeoutMs, serviceId, sendJson } = options; - if (!cloudApiBaseUrl) { - sendJson(response, 503, { error: "cloud_api_base_url_missing", serviceId, path: "/auth/workspace-bootstrap" }); - return; - } - - const auth = await resolveAuthBootstrap({ request, cloudApiBaseUrl, cloudApiProxyTimeoutMs }); - if (auth.body?.authenticated !== true) { - sendJsonWithForwardedCookies(response, auth.statusCode || 200, auth.body ?? { authenticated: false }, auth.headers); - return; - } - - const projectId = authConfigValueFromSearch(url.searchParams.get("projectId"), DEFAULT_WORKBENCH_PROJECT_ID); - const workspace = await requestCloudApiJson({ - request, - method: "GET", - pathname: `/v1/workbench/workspace?projectId=${encodeURIComponent(projectId)}`, - headers: auth.cookieHeader ? { cookie: auth.cookieHeader } : {}, - cloudApiBaseUrl, - cloudApiProxyTimeoutMs - }); - const body = { - ...(auth.body ?? { authenticated: true }), - projectId, - workspace: workspace.ok ? workspace.body?.workspace ?? null : null, - workspaceStatus: workspace.statusCode || null, - workspaceError: workspace.ok ? null : workspace.body?.error ?? workspace.body?.message ?? null - }; - sendJsonWithForwardedCookies(response, auth.statusCode || 200, body, auth.headers); -} - async function resolveAuthBootstrap({ request, cloudApiBaseUrl, cloudApiProxyTimeoutMs }) { const session = await requestCloudApiJson({ request, method: "GET", pathname: "/auth/session", cloudApiBaseUrl, cloudApiProxyTimeoutMs }); return withCookieHeader(request, session); } -function authConfigValueFromSearch(value, fallback) { - return typeof value === "string" && value.trim() ? value.trim() : fallback; -} - function requestCloudApiJson({ request, method, pathname, body = "", headers = {}, cloudApiBaseUrl, cloudApiProxyTimeoutMs }) { return new Promise((resolve) => { let settled = false; diff --git a/web/hwlab-cloud-web/index.html b/web/hwlab-cloud-web/index.html index 8b5f94de..3e022d9d 100644 --- a/web/hwlab-cloud-web/index.html +++ b/web/hwlab-cloud-web/index.html @@ -16,7 +16,7 @@ try { projectId = window.localStorage.getItem("hwlab.workbench.projectId.v1"); } catch (_) { projectId = null; } } if (!/^prj_[A-Za-z0-9_.:-]{3,96}$/.test(projectId || "")) projectId = "prj_hwpod_workbench"; - window.HWLAB_CLOUD_WEB_EARLY_WORKSPACE_BOOTSTRAP = fetch("/auth/workspace-bootstrap?projectId=" + encodeURIComponent(projectId), { + window.HWLAB_CLOUD_WEB_EARLY_WORKSPACE_BOOTSTRAP = fetch("/v1/workbench/workspace?projectId=" + encodeURIComponent(projectId), { credentials: "same-origin", headers: { accept: "application/json" } }).then(function (response) { diff --git a/web/hwlab-cloud-web/scripts/check.ts b/web/hwlab-cloud-web/scripts/check.ts index d0a2dafa..40334ebd 100644 --- a/web/hwlab-cloud-web/scripts/check.ts +++ b/web/hwlab-cloud-web/scripts/check.ts @@ -61,6 +61,8 @@ const appSource = readCloudWebAppSource(rootDir); assert.match(html, /