@gen3/workspaces 0.12.71 → 0.12.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["../../../src/constants.ts","../../../src/server/workspaceAssetsHandler.ts","../../../src/server/withJupyterWorkspaces.ts","../../../src/server/utils.ts","../../../src/server/kernelLifecycleProxy.ts","../../../src/api/workspaceAssetsApi.ts","../../../src/api/workspaceGatewayApiHandler.ts","../../../src/api/kernelApiHandler.ts","../../../src/server/hatcheryProxy.ts","../../../src/api/hatcheryApiHandler.ts"],"sourcesContent":["import { GEN3_API, GEN3_WORKSPACE_API } from '@gen3/core';\n\n// TODO: migrate this to @gen3/core\n\nexport const GEN3_HATCHERY_API =\n GEN3_WORKSPACE_API || '/workspace-api/workspace/hatchery'; // get replaced by revproxy\n\nexport const GEN3_KERNEL_API =\n process.env.GEN3_KERNEL_API || `${GEN3_API}/lw-workspace/proxy/jeg-panel/api`;\n\nexport const GEN3_JEG_GATEWAY_API =\n process.env.JEG_GATEWAY_API || `${GEN3_API}/lw-workspace/proxy/jeg-panel/api`;\n\n// TODO: resolve this with @gen3/core\nexport const GEN3_WORKSPACES_API =\n GEN3_WORKSPACE_API || `${GEN3_API}/lw-workspace`;\n\nexport const JEG_SERVICE_API =\n 'http://jupyter-enterprise-gateway.jupyter-pods.svc.cluster.local:8888';\n","/**\n * Next.js API route handler factory for serving JupyterLite static assets.\n *\n * Usage (consumer's `src/pages/api/workspace-assets/[tier]/[[...path]].ts`):\n *\n * import { createWorkspaceAssetsHandler } from '@gen3/jupyter-workspaces/server';\n * export default createWorkspaceAssetsHandler();\n *\n * Or with custom config:\n *\n * export default createWorkspaceAssetsHandler({\n * gatewayBaseUrl: '/api/workspace/gateway/',\n * });\n *\n * `workspaceAssetsApi` (this package's default wiring) builds its options from\n * `<GEN3_FRONTEND_CONFIGURATION_ROOT>/<GEN3_COMMONS_NAME>/workspaceAssets.json`,\n * so per-commons branding and gateway routing need no code changes.\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport nodePath from 'path';\nimport fs from 'fs';\nimport { getCookie } from 'cookies-next';\n\nconst MAX_FILE_SIZE_BYTES = 67108864; // 64 * 1024 * 1024\n\n// ---------- types ----------\n\nexport interface WorkspaceAssetsHandlerOptions {\n /** Gateway base URL injected into remote tier config (default: env JUPYTER_GATEWAY_BASE_URL or '/api/workspace/gateway/') */\n gatewayBaseUrl?: string;\n /**\n * Root directory containing the JupyterLite assets.\n * Default: `<cwd>/node_modules/@gen3/jupyter-workspaces/assets`\n */\n assetRoot?: string;\n /** Additional JupyterLite extensions to disable for the remote tier */\n additionalDisabledExtensions?: string[];\n /** Application name injected into JupyterLite config data and used as <title> override (opt-in branding). */\n appName?: string;\n /** Favicon URL injected into JupyterLite config data (opt-in branding). */\n faviconUrl?: string;\n /**\n * `<title>` override for served JupyterLite HTML. Defaults to `appName` when\n * omitted; set it when the window title should differ from the config-data\n * `appName` JupyterLite reports internally.\n */\n pageTitle?: string;\n /**\n * Origin-relative path used to build the absolute `remoteKernelsBaseUrl`\n * injected into the remote tier (e.g. `/lw-workspace/proxy/jeg-proxy`).\n * The origin is resolved per-request from forwarding headers so JupyterLite\n * does not resolve kernel endpoints relative to the assets route.\n * Omitted → `remoteKernelsBaseUrl` is not injected.\n */\n remoteKernelsPath?: string;\n /** Override for the remote tier's `fullThemesUrl` (default: `/workspace-api/workspace-assets/remote/build/themes`). */\n fullThemesUrl?: string;\n}\n\n// ---------- constants ----------\n\nconst ALLOWED_TIERS = new Set(['free', 'remote']);\n\nconst SAFE_SEGMENT_RE = /^@?[A-Za-z0-9._-]+$/;\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.wasm': 'application/wasm',\n '.txt': 'text/plain; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.woff': 'font/woff',\n '.ttf': 'font/ttf',\n '.map': 'application/json; charset=utf-8',\n '.ipynb': 'application/json; charset=utf-8',\n};\n\nconst DEFAULT_FULL_THEMES_URL =\n '/workspace-api/workspace-assets/remote/build/themes';\n\nconst REMOTE_DISABLED_EXTENSIONS = [\n '@jupyterlite/services-extension:config-section-manager',\n '@jupyterlite/services-extension:default-drive',\n '@jupyterlite/services-extension:event-manager',\n '@jupyterlite/services-extension:exporters',\n '@jupyterlite/services-extension:kernel-manager',\n '@jupyterlite/services-extension:kernel-client',\n '@jupyterlite/services-extension:kernel-spec-client',\n '@jupyterlite/services-extension:kernel-spec-manager',\n '@jupyterlite/services-extension:kernel-specs',\n '@jupyterlite/services-extension:nbconvert-manager',\n '@jupyterlite/services-extension:session-manager',\n '@jupyterlite/application-extension:service-worker-manager',\n '@jupyterlab/apputils-extension:themes',\n];\n\n// ---------- helpers ----------\n\nconst ASSETS_ROOT_PATH =\n process.env.JUPYTER_ASSETS_ROOT_PATH || '/gen3/jupyter-workspaces/assets';\n\nfunction defaultAssetRoot(): string {\n return ASSETS_ROOT_PATH.startsWith('/')\n ? ASSETS_ROOT_PATH\n : nodePath.join(process.cwd(), ASSETS_ROOT_PATH);\n}\ninterface BrandingConfig {\n appName?: string;\n faviconUrl?: string;\n pageTitle?: string;\n}\n\nconst DEFAULT_REMOTE_BRANDING: BrandingConfig = {\n appName: 'JupyterLite',\n faviconUrl: '/favicon2.ico',\n};\n\n/** Escape characters that are special inside an HTML text node / attribute. */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;');\n}\n\n/**\n * Replace the document title with the configured page title (or app name).\n * Values originate from a server-side config file, but they are escaped so a\n * stray `<` in a commons name cannot break out of the title element.\n */\nfunction replaceTitle(html: string, branding: BrandingConfig): string {\n const title = branding.pageTitle ?? branding.appName;\n if (!title) return html;\n return html.replace(\n /<title>[^<]*<\\/title>/,\n `<title>${escapeHtml(title)}</title>`,\n );\n}\n\n/**\n * Resolve the origin from forwarding headers, with referer fallback.\n * Handles proxies that drop non-standard ports from the Host header.\n */\nfunction resolveOrigin(req: NextApiRequest): { proto: string; host: string } {\n const forwardedProto =\n (Array.isArray(req.headers['x-forwarded-proto'])\n ? req.headers['x-forwarded-proto'][0]\n : req.headers['x-forwarded-proto']) || 'http';\n const forwardedHost = Array.isArray(req.headers['x-forwarded-host'])\n ? req.headers['x-forwarded-host'][0]\n : req.headers['x-forwarded-host'];\n const hostHeader = Array.isArray(req.headers.host)\n ? req.headers.host[0]\n : req.headers.host;\n const refererHeader = Array.isArray(req.headers.referer)\n ? req.headers.referer[0]\n : req.headers.referer;\n\n let resolvedHost = (forwardedHost || hostHeader || '').trim();\n let resolvedProto = String(forwardedProto).trim() || 'http';\n\n if (refererHeader) {\n try {\n const refererUrl = new URL(refererHeader);\n if (!resolvedHost || !resolvedHost.includes(':')) {\n resolvedHost = refererUrl.host;\n }\n if (!resolvedProto) {\n resolvedProto = refererUrl.protocol.replace(':', '');\n }\n } catch {\n // Ignore malformed referer and keep header-derived values.\n }\n }\n\n if (!resolvedHost) {\n resolvedHost = 'localhost:8890';\n }\n\n return { proto: resolvedProto, host: resolvedHost };\n}\n\ninterface RemoteInjectionConfig {\n gatewayBaseUrl: string;\n disabledExtensions: string[];\n fullThemesUrl: string;\n remoteKernelsPath?: string;\n branding?: BrandingConfig;\n}\n\nfunction injectRemoteConfig(\n html: string,\n req: NextApiRequest,\n config: RemoteInjectionConfig,\n): string {\n const {\n gatewayBaseUrl,\n disabledExtensions,\n fullThemesUrl,\n remoteKernelsPath,\n } = config;\n const branding = config.branding ?? DEFAULT_REMOTE_BRANDING;\n\n const { proto, host } = resolveOrigin(req);\n const absoluteGatewayBase = `${proto}://${host}${gatewayBaseUrl}`;\n\n // Inject server-side JEG token — overrides any client-supplied auth header.\n // This ensures calls from JupyterLite's own serverconnection.js are also authenticated.\n\n let accessToken = undefined;\n if (process.env.NODE_ENV === 'development') {\n // NOTE: This cookie can only be accessed from the client side\n // in development mode. Otherwise, the cookie is set as httpOnly\n accessToken = getCookie('credentials_token');\n }\n\n const configData: Record<string, unknown> = {\n remoteBaseUrl: absoluteGatewayBase,\n remoteToken: accessToken,\n disabledExtensions,\n fullThemesUrl,\n // Required so JupyterLab sets window.jupyterapp, which the parent\n // frame uses for polling readiness and attaching remote kernels.\n exposeAppInBrowser: 'true',\n };\n\n if (remoteKernelsPath) {\n // Absolute so JupyterLite does not resolve kernel ops relative to\n // /workspace-api/workspace-assets/remote/. Routing all kernel traffic\n // through jeg-proxy lets JupyterLite see merged container + JEG kernelspecs.\n configData.remoteKernelsBaseUrl = `${proto}://${host}${remoteKernelsPath}`;\n }\n\n if (branding?.appName) configData.appName = branding.appName;\n if (branding?.faviconUrl) configData.faviconUrl = branding.faviconUrl;\n\n const result = html.replace(\n /(<script\\s+id=\"jupyter-config-data\"[^>]*>)\\s*(\\{[^]*?\\})\\s*(<\\/script>)/,\n (_match, openTag: string, existingJson: string, closeTag: string) => {\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(existingJson);\n } catch {\n // empty or malformed — start fresh\n }\n const merged = { ...existing, ...configData };\n if (Array.isArray(existing.disabledExtensions)) {\n const combined = new Set([\n ...(existing.disabledExtensions as string[]),\n ...disabledExtensions,\n ]);\n merged.disabledExtensions = [...combined];\n }\n return `${openTag}${JSON.stringify(merged)}${closeTag}`;\n },\n );\n\n return replaceTitle(result, branding);\n}\n\nfunction injectBranding(html: string, branding: BrandingConfig): string {\n const result = html.replace(\n /(<script\\s+id=\"jupyter-config-data\"[^>]*>)\\s*(\\{[^]*?\\})\\s*(<\\/script>)/,\n (_match, openTag: string, existingJson: string, closeTag: string) => {\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(existingJson);\n } catch (error: unknown) {\n // empty or malformed — start fresh\n if (error instanceof Error) {\n console.warn('Failed to parse existing JSON', error.message);\n } else {\n console.warn('Failed to parse existing JSON', error);\n }\n }\n if (branding.appName) existing.appName = branding.appName;\n if (branding.faviconUrl) existing.faviconUrl = branding.faviconUrl;\n return `${openTag}${JSON.stringify(existing)}${closeTag}`;\n },\n );\n\n return replaceTitle(result, branding);\n}\n\n// ---------- factory ----------\n\nexport function createWorkspaceAssetsHandler(\n options?: WorkspaceAssetsHandlerOptions,\n) {\n const gatewayBaseUrl =\n options?.gatewayBaseUrl ??\n process.env.JUPYTER_GATEWAY_BASE_URL ??\n '/api/workspace/gateway/';\n\n const assetRoot = options?.assetRoot ?? defaultAssetRoot();\n\n // Keep this in for logging purposes\n console.log('jupyterlite assets root:', assetRoot);\n\n const disabledExtensions = options?.additionalDisabledExtensions\n ? [...REMOTE_DISABLED_EXTENSIONS, ...options.additionalDisabledExtensions]\n : REMOTE_DISABLED_EXTENSIONS;\n\n const branding: BrandingConfig | undefined =\n options?.appName || options?.faviconUrl || options?.pageTitle\n ? {\n appName: options.appName,\n faviconUrl: options.faviconUrl,\n pageTitle: options.pageTitle,\n }\n : undefined;\n\n const remoteInjectionConfig: RemoteInjectionConfig = {\n gatewayBaseUrl,\n disabledExtensions,\n fullThemesUrl: options?.fullThemesUrl ?? DEFAULT_FULL_THEMES_URL,\n remoteKernelsPath: options?.remoteKernelsPath,\n branding,\n };\n\n // Build the allowed-file sets once at factory time (not per-request) to\n // avoid unbounded I/O on every incoming request (CWE-770).\n const walkDir = (dir: string, set: Set<string>): void => {\n try {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = nodePath.join(dir, entry.name);\n if (entry.isDirectory()) {\n walkDir(full, set);\n } else {\n set.add(full);\n }\n }\n } catch {\n // Tier directory doesn't exist yet — set remains empty and handler will 404.\n }\n };\n\n const allowedFilesByTier: Record<string, Set<string>> = {\n free: new Set<string>(),\n remote: new Set<string>(),\n };\n for (const tier of ALLOWED_TIERS) {\n walkDir(nodePath.resolve(assetRoot, tier), allowedFilesByTier[tier]);\n }\n\n return function handler(req: NextApiRequest, res: NextApiResponse): void {\n const { tier, path: pathSegments } = req.query;\n\n if (typeof tier !== 'string' || !ALLOWED_TIERS.has(tier)) {\n res.status(404).end('Not found');\n return;\n }\n\n const segments: string[] = Array.isArray(pathSegments)\n ? pathSegments\n : pathSegments\n ? [pathSegments]\n : [];\n\n let tierRoot: string;\n if (tier === 'free') {\n tierRoot = nodePath.resolve(assetRoot, 'free');\n } else if (tier === 'remote') {\n tierRoot = nodePath.resolve(assetRoot, 'remote');\n } else {\n res.status(404).end('Not found');\n return;\n }\n\n const safeSegments: string[] = [];\n for (const seg of segments) {\n if (\n typeof seg !== 'string' ||\n !SAFE_SEGMENT_RE.test(seg) ||\n seg === '.' ||\n seg === '..'\n ) {\n res.status(403).end('Forbidden');\n return;\n }\n safeSegments.push(nodePath.basename(seg));\n }\n\n const allowedFiles = allowedFilesByTier[tier];\n\n const candidatePath = nodePath.resolve(tierRoot, ...safeSegments);\n const candidateIndex = nodePath.join(candidatePath, 'index.html');\n\n console.log('serving jupyterlite asset from', candidatePath);\n\n let filePath: string;\n if (allowedFiles.has(candidatePath)) {\n filePath = candidatePath;\n } else if (allowedFiles.has(candidateIndex)) {\n filePath = candidateIndex;\n } else {\n res.status(404).end('Not found');\n return;\n }\n\n const ext = nodePath.extname(filePath).toLowerCase();\n const contentType = MIME_TYPES[ext] || 'application/octet-stream';\n\n const isBuildAsset =\n filePath.includes(nodePath.join(tier, 'build')) ||\n filePath.includes(nodePath.join(tier, 'extensions'));\n\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');\n res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');\n res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');\n\n if (process.env.NODE_ENV === 'development') {\n // In dev there is no fence service to plant the access_token cookie, so\n // we derive it from credentials_token (which is NOT httpOnly in dev) and\n // set it here. The browser will then send it automatically with every\n // subsequent request to the same origin — including JupyterLite's direct\n // calls to /lw-workspace/proxy/jeg-proxy/api/kernelspecs (which bypass\n // the Next.js proxy and therefore need the cookie on the wire).\n const accessToken = req.cookies?.['credentials_token'];\n if (accessToken) {\n res.setHeader(\n 'Set-Cookie',\n `access_token=${encodeURIComponent(accessToken)}; Path=/; SameSite=Lax`,\n );\n }\n }\n\n if (nodePath.basename(filePath) === 'service-worker.js') {\n res.setHeader('Service-Worker-Allowed', '/');\n }\n\n const isRemoteLabHtml =\n tier === 'remote' &&\n ext === '.html' &&\n filePath.includes(nodePath.join('lab', 'index.html'));\n\n if (isRemoteLabHtml) {\n res.setHeader('Content-Type', contentType);\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n try {\n const html = fs.readFileSync(filePath, 'utf-8');\n const injected = injectRemoteConfig(html, req, remoteInjectionConfig);\n res.status(200).send(injected);\n } catch {\n res.status(500).end('Internal server error');\n }\n return;\n }\n\n // Non-remote HTML (e.g. free-tier lab) — apply branding if configured\n const isHtmlResponse = ext === '.html';\n if (isHtmlResponse && branding) {\n res.setHeader('Content-Type', contentType);\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n try {\n const html = fs.readFileSync(filePath, 'utf-8');\n res.status(200).send(injectBranding(html, branding));\n } catch {\n res.status(500).end('Internal server error');\n }\n return;\n }\n\n res.setHeader('Content-Type', contentType);\n res.setHeader(\n 'Cache-Control',\n isBuildAsset\n ? 'public, max-age=31536000, immutable'\n : 'public, max-age=3600, must-revalidate',\n );\n\n const stat = fs.statSync(filePath);\n if (stat.size > MAX_FILE_SIZE_BYTES) {\n res.status(413).end('File too large');\n return;\n }\n\n const stream = fs.createReadStream(filePath);\n stream.on('error', () => {\n res.status(500).end('Internal server error');\n });\n stream.pipe(res);\n };\n}\n\n/**\n * Default handler — for one-liner re-exports.\n *\n * Built lazily on first request: `createWorkspaceAssetsHandler` walks both tier\n * asset trees at factory time, and this module is imported transitively by\n * `next.config.js` (via `@gen3/workspaces/server`), where that I/O is wasted.\n */\nlet lazyDefaultHandler:\n ReturnType<typeof createWorkspaceAssetsHandler> | undefined;\n\nconst defaultHandler = (req: NextApiRequest, res: NextApiResponse): void => {\n if (!lazyDefaultHandler) {\n lazyDefaultHandler = createWorkspaceAssetsHandler();\n }\n return lazyDefaultHandler(req, res);\n};\n\nexport default defaultHandler;\n","/**\n * Next.js config wrapper that adds all workspace-related plumbing.\n *\n * Usage (consumer's `next.config.js`):\n *\n * const { withJupyterWorkspaces } = require('@gen3/workspaces/server');\n * module.exports = withJupyterWorkspaces(yourNextConfig);\n */\n\nimport type { NextConfig } from 'next';\nimport nodePath from 'path';\nimport type { WebpackConfigContext } from 'next/dist/server/config-shared';\nimport type { Configuration } from 'webpack';\n\nexport interface WithJupyterWorkspacesOptions {\n /**\n * URL of the gateway proxy for local dev rewrites.\n * Default: env `GATEWAY_PROXY_URL` or `http://localhost:8890`\n */\n gatewayProxyUrl?: string;\n /**\n * Workspace page routes that need COOP/COEP headers.\n * Default: ['/workspaces/jupyter', '/workspaces/jupyter-lite', '/workspaces/jupyter-kernel']\n */\n workspaceRoutes?: string[];\n}\n\nconst DEFAULT_WORKSPACE_ROUTES = ['/Workspaces'];\n\nexport function withJupyterWorkspaces(\n nextConfig: NextConfig,\n options?: WithJupyterWorkspacesOptions,\n): NextConfig {\n const workspaceRoutes = options?.workspaceRoutes ?? DEFAULT_WORKSPACE_ROUTES;\n\n return {\n ...nextConfig,\n\n // Merge transpilePackages\n transpilePackages: [\n ...(nextConfig.transpilePackages ?? []),\n ...['@gen3/workspaces'].filter(\n (pkg) => !(nextConfig.transpilePackages ?? []).includes(pkg),\n ),\n ],\n\n // Merge webpack config — add React dedup alias\n webpack(config: Configuration, ctx: WebpackConfigContext) {\n config.resolve = config.resolve ?? {};\n config.resolve.alias = {\n ...config.resolve.alias,\n react: nodePath.dirname(require.resolve('react/package.json')),\n 'react-dom': nodePath.dirname(\n require.resolve('react-dom/package.json'),\n ),\n };\n\n // Chain the consumer's existing webpack config\n if (typeof nextConfig.webpack === 'function') {\n return nextConfig.webpack(config, ctx);\n }\n return config;\n },\n\n // Merge rewrites — add gateway proxy rewrite in dev mode\n async rewrites() {\n const isDev = process.env.NODE_ENV === 'development';\n\n const existing =\n typeof nextConfig.rewrites === 'function'\n ? await nextConfig.rewrites()\n : [];\n\n if (!isDev) return existing;\n\n const gatewayProxyUrl =\n options?.gatewayProxyUrl ??\n process.env.GATEWAY_PROXY_URL ??\n 'http://localhost:8890';\n\n const gatewayRewrite = {\n source: '/api/workspace/gateway/:path*',\n destination: `${gatewayProxyUrl}/api/workspace/gateway/:path*`,\n };\n\n // rewrites() can return an array or { beforeFiles, afterFiles, fallback }\n if (Array.isArray(existing)) {\n return [gatewayRewrite, ...existing];\n }\n return {\n ...existing,\n beforeFiles: [gatewayRewrite, ...(existing.beforeFiles ?? [])],\n };\n },\n\n // Merge headers — add COOP/COEP for workspace routes\n async headers() {\n const existing =\n typeof nextConfig.headers === 'function'\n ? await nextConfig.headers()\n : [];\n\n const coopCoepHeaders = workspaceRoutes.map((route) => ({\n source: route,\n headers: [\n { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },\n { key: 'Cross-Origin-Embedder-Policy', value: 'credentialless' },\n ],\n }));\n\n return [...existing, ...coopCoepHeaders];\n },\n };\n}\n","/**\n * Shared HTTP proxy utility for server-side proxy handlers.\n * Streams request body through and forwards response status + body.\n *\n * Also exports two token helpers used by the proxy factories:\n * - extractTokenFallback: minimal cookie/header extraction used when the host\n * app has not injected its own getToken (standalone / test use).\n * - decodeJwtClaims: base64url decode of the JWT payload for REMOTE_USER header.\n * Crypto verification is Ambassador's job — we only need the sub/username claim.\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\n\n/**\n * Minimal JWT extraction fallback — used only when the host app does not inject\n * its own getToken. Prefers Authorization: Bearer, then access_token cookie.\n * In gen3-vectis production this is never reached — getAccessToken is always wired.\n */\nexport function extractTokenFallback(req: NextApiRequest): string | null {\n const auth = req.headers['authorization'];\n if (typeof auth === 'string' && auth.startsWith('Bearer ')) {\n return auth.slice(7).trim() || null;\n }\n const cookie = req.headers['cookie'] ?? '';\n const m = cookie.match(/(?:^|;\\s*)access_token=([^;]+)/);\n return m ? decodeURIComponent(m[1]).trim() || null : null;\n}\n\n/**\n * Decode JWT payload claims without cryptographic verification.\n * Ambassador has already verified the RS256 signature — we just need the sub claim\n * to set the REMOTE_USER header for per-user isolation enforcement downstream.\n */\n// Maximum JWT string length accepted before base64 decoding.\n// GA4GH RAS Passport JWTs embed multiple signed Visa JWTs as claims, so the\n// outer passport can easily exceed 8 KiB (50 visas × ~2 KB each ≈ 136 KB encoded).\n// 512 KiB covers the most complex real-world passports while still guarding against\n// crafted JWTs designed to exhaust server memory. Ambassador has already verified\n// the RS256 signature — this cap only defends the local base64/JSON decode step.\nconst MAX_JWT_LENGTH = 524288; // 512 KiB\n\nexport function decodeJwtClaims(jwt: string): Record<string, unknown> | null {\n if (jwt.length > MAX_JWT_LENGTH) return null;\n try {\n const parts = jwt.split('.');\n if (parts.length < 2) return null;\n const padded = parts[1]\n .replace(/-/g, '+')\n .replace(/_/g, '/')\n .padEnd(Math.ceil(parts[1].length / 4) * 4, '=');\n return JSON.parse(Buffer.from(padded, 'base64').toString('utf8')) as Record<\n string,\n unknown\n >;\n } catch {\n return null;\n }\n}\n\nexport interface ProxyRequestOptions {\n req: NextApiRequest;\n res: NextApiResponse;\n targetUrl: string;\n method: 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH';\n extraHeaders?: Record<string, string>;\n /** Whether to stream the incoming request body to the target. */\n forwardBody?: boolean;\n}\n\nexport async function createProxyRequest({\n req,\n res,\n targetUrl,\n method,\n extraHeaders = {},\n forwardBody = false,\n}: ProxyRequestOptions): Promise<void> {\n const headers: Record<string, string> = {\n ...extraHeaders,\n };\n if (\n forwardBody &&\n (method === 'POST' || method === 'PUT' || method === 'PATCH')\n ) {\n headers['Content-Type'] ??= 'application/json';\n }\n\n let body: BodyInit | undefined;\n if (\n forwardBody &&\n (method === 'POST' || method === 'PUT' || method === 'PATCH')\n ) {\n let buf: Buffer;\n try {\n buf = await bufferBody(req);\n } catch (err) {\n const statusCode = (err as { statusCode?: number }).statusCode ?? 400;\n const msg = err instanceof Error ? err.message : 'Bad request';\n res.status(statusCode).json({ error: msg });\n return;\n }\n // Node.js Buffer is a Uint8Array subclass; cast to silence DOM BodyInit mismatch\n body = buf as unknown as BodyInit;\n if (buf.length > 0) {\n headers['Content-Length'] = String(buf.length);\n }\n }\n\n let upRes: Response;\n try {\n upRes = await fetch(targetUrl, {\n method,\n headers,\n body,\n signal: AbortSignal.timeout(30_000),\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n res.status(502).json({ error: `Upstream unreachable: ${msg}` });\n return;\n }\n\n // Forward status and content-type\n const contentType = upRes.headers.get('content-type') || 'application/json';\n res.setHeader('Content-Type', contentType);\n\n if (upRes.status === 204 || upRes.status === 304) {\n res.status(upRes.status).end();\n return;\n }\n\n // Do not forward raw upstream error bodies — they may contain stack traces or\n // internal hostnames. Log them server-side (CloudWatch) and return a generic message.\n if (upRes.status >= 500) {\n const errBody = await upRes.text().catch(() => '');\n console.error(\n '[proxy] upstream %d from %s: %s',\n upRes.status,\n targetUrl,\n errBody,\n );\n res.status(502).json({ error: 'Upstream service error.' });\n return;\n }\n\n const responseBody = await upRes.text();\n res.status(upRes.status).send(responseBody);\n}\n\n// Maximum request body size accepted by the proxy (1 MiB).\n// Prevents memory exhaustion from oversized payloads before any business logic runs.\nconst MAX_BODY_BYTES = 1 * 1024 * 1024;\n\nfunction bufferBody(req: NextApiRequest): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let total = 0;\n req.on('data', (chunk: Buffer) => {\n total += chunk.length;\n if (total > MAX_BODY_BYTES) {\n req.destroy();\n reject(\n Object.assign(new Error('Request body too large'), {\n statusCode: 413,\n }),\n );\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n","/**\n * createKernelLifecycleProxyHandler — server-side Next.js API route handler\n * for all kernel control-plane traffic.\n *\n * Security properties:\n * - Billing gate: POST /kernels fetches Fence /credentials/cdis first;\n * if that fails, no kernel is ever launched.\n * - Kernel spec filtering: the browser receives only the names/costs defined in policy.\n * - REMOTE_USER forwarded on every upstream request — JEG enforces per-user isolation.\n * - KERNEL_ID_RE validates all kernel IDs before they reach the upstream URL.\n *\n * Token extraction:\n * Pass getToken to reuse the host app's cookie logic (strongly recommended).\n * In gen3-vectis: `(req) => getAccessToken(req.headers['cookie'] ?? '') ?? null`\n * Ambassador performs RS256 verification before any request reaches Next.js.\n *\n * Usage (src/pages/api/workspace/kernel/[...action].ts — generated by bin/init.mjs):\n * import { createKernelLifecycleProxyHandler } from '@gen3/jupyter-workspaces/server';\n * import { getAccessToken } from '../../lib/auth/getLoginStatus';\n * const policy = process.env.KERNEL_SPEC_POLICY ? JSON.parse(process.env.KERNEL_SPEC_POLICY) : {};\n * export default createKernelLifecycleProxyHandler({\n * gen3Endpoint: process.env.GEN3_ENDPOINT,\n * fenceUrl: process.env.FENCE_URL,\n * kernelSpecPolicy: policy,\n * getToken: (req) => getAccessToken(req.headers['cookie'] ?? '') ?? null,\n * });\n * export const config = { api: { bodyParser: false } };\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { decodeJwtClaims, extractTokenFallback } from './utils';\nimport { fetchFence, GEN3_FENCE_SERVICE } from '@gen3/core';\nimport { GEN3_FENCE_API } from '@gen3/core/server';\nimport { JEG_SERVICE_API } from '../constants';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** Kernel spec filtering and cost annotation policy (server-side only). */\nexport interface KernelSpecPolicy {\n /**\n * Raw JEG kernel spec names that are permitted for this deployment.\n * Only these will be returned to the browser.\n */\n allowedSpecs: string[];\n /**\n * Cost per hour for each spec. 0 = included in base subscription.\n * Injected into the spec as `costPerHour` before returning to browser.\n */\n costPerHour: Record<string, number>;\n /**\n * Human-readable display name per spec (replaces raw JEG spec name).\n * e.g. { \"python3_gpu_a100\": \"Python (GPU A100 — $2.40/hr)\" }\n */\n displayNames: Record<string, string>;\n /**\n * Node type label for UI badge.\n * e.g. { \"python3_micro\": \"micro\", \"python3_gpu_a100\": \"gpu\" }\n */\n nodeType: Record<string, string>;\n}\n\nexport interface BillingEvent {\n username: string;\n action: 'launch' | 'terminate';\n kernelSpec?: string;\n kernelId?: string;\n costTier: number;\n timestamp: string;\n}\n\nexport interface KernelLifecycleProxyConfig {\n /**\n * External hostname for Ambassador routing, e.g. \"mycommons.example.com\"\n * or \"localhost:30080\" in local dev.\n * Used to build the upstream URL: https://{gen3Endpoint}/lw-workspace/proxy/...\n */\n gen3Endpoint: string | undefined;\n /** Internal URL of the Fence service, e.g. http://fence.fence.svc:80 */\n fenceUrl: string | undefined;\n /** Kernel spec filtering + billing policy (server-side only). */\n kernelSpecPolicy: Partial<KernelSpecPolicy>;\n /**\n * Set to true when JEG is configured and enabled for this deployment.\n * Controlled by ENABLE_JEG=true env var in gen3-vectis.\n * When false (default), all routes except GET /api/status return 503 silently so\n * the UI fails gracefully without error spam.\n */\n jegEnabled?: boolean;\n /**\n * Number of idle days before a kernel is considered stale (for /api/reap).\n * Defaults to 10. Controlled by JEG_IDLE_KILL_DAYS env var.\n */\n idleKillDays?: number;\n /**\n * Maximum kernel age in days regardless of idle state (for /api/reap).\n * Defaults to 15. Controlled by JEG_MAX_KERNEL_AGE_DAYS env var.\n */\n maxKernelAgeDays?: number;\n /**\n * Optional billing event sink. Defaults to structured JSON to stdout (CloudWatch).\n * Swap for DynamoDB, Stripe, etc. without changing any other code.\n * The function MUST NOT block — fire and forget.\n */\n billingSink?: (event: BillingEvent) => void;\n /**\n * Token extractor injected by the host application.\n * In gen3-vectis: `(req) => getAccessToken(req.headers['cookie'] ?? '') ?? null`\n * When omitted a minimal Bearer-header/cookie fallback is used (dev/standalone only).\n * Ambassador has already done RS256 verification — this is extraction only.\n */\n getToken?: (req: NextApiRequest) => string | null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Default billing sink — structured CloudWatch-compatible JSON log */\n/* ------------------------------------------------------------------ */\n\nfunction defaultBillingSink(event: BillingEvent): void {\n // CloudWatch Logs Insights picks up structured JSON automatically\n process.stdout.write(\n JSON.stringify({ type: 'WORKSPACE_BILLING', ...event }) + '\\n',\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Fence credential fetch */\n/* ------------------------------------------------------------------ */\n\ninterface FenceCreds {\n key_id: string;\n api_key: string; // pragma: allowlist secret\n}\n\nconst EMPTY_FENCE_CREDS: FenceCreds = {\n key_id: '',\n api_key: '', // pragma: allowlist secret\n};\n\nasync function fetchFenceCreds(\n fenceUrl: string,\n jwt: string,\n): Promise<FenceCreds> {\n let parsedFenceUrl: URL;\n try {\n parsedFenceUrl = new URL(fenceUrl);\n } catch {\n throw new Error('Fence URL is misconfigured.');\n }\n if (\n parsedFenceUrl.protocol !== 'http:' &&\n parsedFenceUrl.protocol !== 'https:'\n ) {\n throw new Error('Fence URL is misconfigured.');\n }\n try {\n const response = await fetchFence<FenceCreds>(\n {\n endpoint: 'credentials/api',\n method: 'GET',\n headers: {\n Authorization: `Bearer ${jwt}`,\n 'Content-Type': 'application/json',\n },\n },\n process.env.NODE_ENV === 'production', // use the FENCE Service if in production\n );\n if (!response?.data?.api_key) {\n console.error('No valid API key found in Fence response');\n return {\n api_key: '', // pragma: allowlist secret\n key_id: '',\n };\n }\n return response.data;\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error('Error fetching API key from Fence:', error);\n } else {\n console.error('Error fetching API key from Fence');\n }\n return EMPTY_FENCE_CREDS;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Kernel spec response transformation */\n/* ------------------------------------------------------------------ */\n\ninterface RawKernelSpecsResponse {\n default: string;\n kernelspecs: Record<\n string,\n {\n name: string;\n spec: {\n display_name: string;\n language: string;\n argv?: string[];\n metadata?: Record<string, unknown>;\n };\n resources?: Record<string, string>;\n }\n >;\n}\n\nfunction filterAndAnnotateSpecs(\n raw: RawKernelSpecsResponse,\n policy: Partial<KernelSpecPolicy>,\n): RawKernelSpecsResponse {\n const allowedSpecs = policy.allowedSpecs ?? [];\n const costPerHour = policy.costPerHour ?? {};\n const displayNames = policy.displayNames ?? {};\n const nodeType = policy.nodeType ?? {};\n\n if (allowedSpecs.length === 0) {\n // No policy configured — return everything unannotated (useful during dev bootstrap)\n return raw;\n }\n\n const filteredSpecs: RawKernelSpecsResponse['kernelspecs'] = {};\n\n for (const specName of allowedSpecs) {\n const rawSpec = raw.kernelspecs[specName];\n if (!rawSpec) continue; // JEG doesn't have this spec — skip silently\n\n filteredSpecs[specName] = {\n ...rawSpec,\n spec: {\n ...rawSpec.spec,\n // Override display_name with our curated name if provided\n display_name: displayNames[specName] ?? rawSpec.spec.display_name,\n // Inject billing metadata into spec.metadata (available to browser)\n metadata: {\n ...rawSpec.spec.metadata,\n costPerHour: costPerHour[specName] ?? 0,\n nodeType: nodeType[specName] ?? 'unknown',\n },\n },\n };\n }\n\n // Use first allowed spec as default if original default was filtered out\n const filteredDefault = allowedSpecs.includes(raw.default)\n ? raw.default\n : (allowedSpecs[0] ?? '');\n\n return { default: filteredDefault, kernelspecs: filteredSpecs };\n}\n\n/* ------------------------------------------------------------------ */\n/* Body buffering (Next.js bodyParser: false) */\n/* ------------------------------------------------------------------ */\n\nfunction readBody(req: NextApiRequest): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => chunks.push(chunk));\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Ambassador upstream URL builder */\n/* ------------------------------------------------------------------ */\n\n// function buildAmbassadorUrl(gen3Endpoint: string, kernelPath: string): string {\n// // gen3Endpoint may or may not have a scheme\n// const base = gen3Endpoint.startsWith('http')\n// ? gen3Endpoint\n// : `https://${gen3Endpoint}`;\n// const parsed = new URL(base);\n// if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n// throw new Error('gen3Endpoint must use http or https protocol.');\n// }\n// return `${parsed.origin}${parsed.pathname.replace(/\\/$/, '')}/lw-workspace/proxy${kernelPath}`;\n// }\n\nfunction buildAmbassadorUrl(gen3Endpoint: string, kernelPath: string): string {\n // gen3Endpoint may or may not have a scheme\n const base = gen3Endpoint.startsWith('http')\n ? gen3Endpoint\n : `https://${gen3Endpoint}`;\n const parsed = new URL(base);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error('gen3Endpoint must use http or https protocol.');\n }\n return `${parsed.origin}${parsed.pathname.replace(/\\/$/, '')}/lw-workspace/proxy${kernelPath}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Route matching */\n/* ------------------------------------------------------------------ */\n\nconst KERNEL_ID_RE = /^[a-f0-9-]{8,36}$/i;\n\ntype KernelRoute =\n | { type: 'kernelspecs' }\n | { type: 'kernels_list' }\n | { type: 'kernel_launch' }\n | { type: 'kernel_delete'; kernelId: string }\n | { type: 'kernel_passthrough'; kernelPath: string }\n | { type: 'status' }\n | { type: 'reap' };\n\ntype SimpleRoute = Exclude<\n KernelRoute,\n { type: 'kernel_delete' | 'kernel_passthrough' }\n>;\n\n// Table-driven simple routes: all match /api/{resource} with no kernel ID segment.\nconst SIMPLE_ROUTES = new Map<string, SimpleRoute>([\n ['GET:status', { type: 'status' }],\n ['POST:reap', { type: 'reap' }],\n ['GET:kernelspecs', { type: 'kernelspecs' }],\n ['GET:kernels', { type: 'kernels_list' }],\n ['POST:kernels', { type: 'kernel_launch' }],\n]);\n\nfunction resolveKernelRoute(\n method: string,\n actionSegments: string[],\n): KernelRoute | null {\n const [seg1, seg2] = actionSegments;\n\n if (!seg2) {\n return SIMPLE_ROUTES.get(`${method}:${seg1}`) ?? null;\n }\n\n // Routes with a kernel ID segment — validate format before use.\n if (seg1 === 'kernels' && KERNEL_ID_RE.test(seg2)) {\n if (method === 'DELETE') {\n return { type: 'kernel_delete', kernelId: seg2 };\n }\n // GET /api/kernels/{id}/channels or similar (passthrough for WebSocket upgrade info)\n if (method === 'GET') {\n const rest = actionSegments.slice(2).join('/');\n return {\n type: 'kernel_passthrough',\n kernelPath: `/api/kernels/${seg2}/${rest}`,\n };\n }\n }\n\n return null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Main factory — shared types and per-route handlers */\n/* ------------------------------------------------------------------ */\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\ninterface RouteContext {\n req: NextApiRequest;\n gen3Endpoint: string;\n fenceUrl: string | undefined;\n kernelSpecPolicy: Partial<KernelSpecPolicy>;\n ambassadorHeaders: Record<string, string>;\n /** Unsanitised JWT — use only for non-header contexts (e.g. Fence fetch body). */\n jwt: string;\n username: string;\n sink: (event: BillingEvent) => void;\n idleKillDays: number;\n maxKernelAgeDays: number;\n}\n\n/* -------- GET /api/kernelspecs -------- */\nasync function handleKernelSpecs(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernelspecs');\n try {\n const upRes = await fetch(upstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n if (!upRes.ok) {\n res\n .status(upRes.status)\n .json({ error: `Gateway ${upRes.status}: ${upRes.statusText}` });\n return;\n }\n const rawSpecs = (await upRes.json()) as RawKernelSpecsResponse;\n res\n .status(200)\n .json(filterAndAnnotateSpecs(rawSpecs, ctx.kernelSpecPolicy));\n } catch {\n res.status(502).json({ error: 'Failed to fetch kernel specs.' });\n }\n}\n\n/* -------- GET /api/kernels -------- */\nasync function handleKernelsList(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernels');\n try {\n const upRes = await fetch(upstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n if (!upRes.ok) {\n res\n .status(upRes.status)\n .json({ error: `Gateway ${upRes.status}: ${upRes.statusText}` });\n return;\n }\n res.status(200).json(await upRes.json());\n } catch {\n res.status(502).json({ error: 'Failed to list kernels.' });\n }\n}\n\n/* -------- POST /api/reap — bulk-delete stale/aged kernels -------- */\nasync function handleReap(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n // const listUpstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernels');\n const listUpstream = `${ctx.gen3Endpoint}/api/kernels`;\n let kernelList: Array<{ id: string; name: string; last_activity?: string }> =\n [];\n try {\n const listRes = await fetch(listUpstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n\n if (!listRes.ok) {\n res\n .status(listRes.status)\n .json({ error: `Failed to list kernels: ${listRes.status}` });\n return;\n }\n kernelList = (await listRes.json()) as typeof kernelList;\n } catch (err) {\n res.status(502).json({ error: `Kernel list unavailable: ${errMsg(err)}` });\n return;\n }\n\n const now = Date.now();\n const idleKillMins = ctx.idleKillDays * 24 * 60;\n const maxAgeMins = ctx.maxKernelAgeDays * 24 * 60;\n const reaped: string[] = [];\n const errors: string[] = [];\n\n for (const kernel of kernelList) {\n if (!KERNEL_ID_RE.test(kernel.id)) continue; // skip any malformed IDs from upstream\n const lastActivity = kernel.last_activity\n ? new Date(kernel.last_activity).getTime()\n : 0;\n const idleMins =\n lastActivity > 0 ? (now - lastActivity) / 60_000 : Infinity;\n if (idleMins <= idleKillMins && idleMins <= maxAgeMins) continue;\n\n const deleteUpstream = buildAmbassadorUrl(\n ctx.gen3Endpoint,\n `/api/kernels/${encodeURIComponent(kernel.id)}`,\n );\n try {\n await fetch(deleteUpstream, {\n method: 'DELETE',\n headers: ctx.ambassadorHeaders,\n });\n reaped.push(kernel.id);\n ctx.sink({\n username: ctx.username,\n action: 'terminate',\n kernelId: kernel.id,\n costTier: 0,\n timestamp: new Date().toISOString(),\n });\n } catch {\n errors.push(kernel.id);\n }\n }\n\n res.status(200).json({ reaped, errors });\n}\n\n/* -------- POST /api/kernels — launch with Fence cred injection -------- */\nasync function handleKernelLaunch(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n if (!ctx.fenceUrl) {\n res.status(503).json({ error: 'FENCE_URL is not configured.' });\n return;\n }\n\n // 1. Fetch per-user S3 credentials from Fence.\n // If this fails, we return 502 and do NOT launch a kernel.\n let fenceCreds: FenceCreds;\n try {\n fenceCreds = await fetchFenceCreds(ctx.fenceUrl, ctx.jwt);\n } catch (err) {\n res\n .status(502)\n .json({ error: `Storage credentials unavailable: ${errMsg(err)}` });\n return;\n }\n\n // 2. Read the original launch body from the client.\n const rawBody = await readBody(ctx.req);\n let launchBody: Record<string, unknown> = {};\n try {\n launchBody = JSON.parse(rawBody.toString('utf8')) as Record<\n string,\n unknown\n >;\n } catch {\n // empty or invalid JSON — proceed with empty body\n }\n\n const kernelSpec = (launchBody.name as string) || '';\n\n // 3. Inject gen3-fuse credential env vars into the kernel launch body.\n // JEG forwards these to the kernel pod → init container writes /.gen3/credentials.json\n // → gen3-fuse sidecar mounts the user's S3 bucket.\n const enrichedBody = {\n ...launchBody,\n env: {\n ...(launchBody.env as Record<string, string>),\n GEN3_API_KEY_ID: fenceCreds.key_id,\n GEN3_API_KEY_SECRET: fenceCreds.api_key, // pragma: allowlist secret\n NAMESPACE: process.env.NAMESPACE || 'jupyter-pods',\n GEN3_ENDPOINT: ctx.gen3Endpoint,\n },\n };\n\n // 4. Non-blocking billing event (launch intent).\n const launchTimestamp = new Date().toISOString();\n const costTier = ctx.kernelSpecPolicy.costPerHour?.[kernelSpec] ?? 0;\n ctx.sink({\n username: ctx.username,\n action: 'launch',\n kernelSpec,\n costTier,\n timestamp: launchTimestamp,\n });\n\n // TODO:\n // BILLING_HOOK: pricing/quota check — runs before kernel is launched.\n // Replace the resolved value below with an async pricing/quota API call.\n // Return false here to block launch with a 402 Payment Required.\n // Example: const approved = await checkQuotaAndPrice({ username, kernelSpec, costTier });\n const billingApproved = true; // TODO: hook pricing gate here\n if (!billingApproved) {\n res\n .status(402)\n .json({ error: 'Kernel launch requires billing authorization.' });\n return;\n }\n\n // 5. Forward to JEG via Ambassador.\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernels');\n let launchRes: Response;\n try {\n launchRes = await fetch(upstream, {\n method: 'POST',\n headers: { ...ctx.ambassadorHeaders, 'Content-Type': 'application/json' },\n body: JSON.stringify(enrichedBody),\n });\n } catch (err) {\n res.status(502).json({ error: `Kernel launch failed: ${errMsg(err)}` });\n return;\n }\n\n if (!launchRes.ok) {\n res.status(launchRes.status).json({\n error: `Kernel launch failed: ${launchRes.status} ${launchRes.statusText}`,\n });\n return;\n }\n\n const kernelData = (await launchRes.json()) as Record<string, unknown>;\n\n // 6. Non-blocking: record kernelId in billing log.\n const kernelId = kernelData?.id as string | undefined;\n if (kernelId) {\n ctx.sink({\n username: ctx.username,\n action: 'launch',\n kernelSpec,\n kernelId,\n costTier,\n timestamp: launchTimestamp,\n });\n }\n\n res.status(201).json(kernelData);\n}\n\n/* -------- DELETE /api/kernels/{id} -------- */\nasync function handleKernelDelete(\n ctx: RouteContext,\n route: Extract<KernelRoute, { type: 'kernel_delete' }>,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(\n ctx.gen3Endpoint,\n `/api/kernels/${encodeURIComponent(route.kernelId)}`,\n );\n try {\n const upRes = await fetch(upstream, {\n method: 'DELETE',\n headers: ctx.ambassadorHeaders,\n });\n // 404 = already gone = success (idempotent terminate)\n if (!upRes.ok && upRes.status !== 404) {\n res.status(upRes.status).json({\n error: `Kernel terminate failed: ${upRes.status} ${upRes.statusText}`,\n });\n return;\n }\n } catch (err) {\n res.status(502).json({ error: `Kernel terminate failed: ${errMsg(err)}` });\n return;\n }\n\n // Non-blocking billing event (terminate)\n ctx.sink({\n username: ctx.username,\n action: 'terminate',\n kernelId: route.kernelId,\n costTier: 0, // actual cost determined from launch event by billing system\n timestamp: new Date().toISOString(),\n });\n\n res.status(204).end();\n}\n\n/* -------- GET /api/kernels/{id}/... passthrough -------- */\nasync function handleKernelPassthrough(\n ctx: RouteContext,\n route: Extract<KernelRoute, { type: 'kernel_passthrough' }>,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, route.kernelPath);\n try {\n const upRes = await fetch(upstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n res.status(upRes.status).json(await upRes.json().catch(() => ({})));\n } catch {\n res.status(502).json({ error: 'Upstream unreachable.' });\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Factory */\n/* ------------------------------------------------------------------ */\n\nconst ALLOWED_FENCE_URLS = [GEN3_FENCE_SERVICE, GEN3_FENCE_API];\n\nconst ALLOWED_JEG_URLS = [JEG_SERVICE_API, '/lw-workspace/proxy/jeg-panel'];\n\nexport function createKernelProxyHandler(config: KernelLifecycleProxyConfig) {\n const sink = config.billingSink ?? defaultBillingSink;\n const jegEnabled = config.jegEnabled === true;\n const idleKillDays = config.idleKillDays ?? 10;\n const maxKernelAgeDays = config.maxKernelAgeDays ?? 15;\n\n return async function kernelLifecycleProxyHandler(\n req: NextApiRequest,\n res: NextApiResponse,\n ): Promise<void> {\n const { gen3Endpoint, fenceUrl, kernelSpecPolicy } = config;\n\n if (fenceUrl && !ALLOWED_FENCE_URLS.includes(fenceUrl)) {\n res.status(503).json({ error: 'Fence service URL is misconfigured.' });\n return;\n }\n\n if (gen3Endpoint && !ALLOWED_JEG_URLS.includes(gen3Endpoint)) {\n res.status(503).json({ error: 'JEG service URL is misconfigured.' });\n return;\n }\n\n // --- Route resolution (done early so /api/status can short-circuit) ---\n const rawAction = req.query.action;\n const actionSegments: string[] = Array.isArray(rawAction)\n ? rawAction.filter((s): s is string => typeof s === 'string')\n : [];\n const route = resolveKernelRoute(req.method || '', actionSegments);\n\n // GET /api/status is the JEG feature-gate probe — always returns 200 with { enabled }.\n // This allows useGatewayConnection to detect whether JEG is configured before polling.\n if (route?.type === 'status') {\n res.setHeader('Cache-Control', 'no-store');\n res.status(200).json({ enabled: jegEnabled });\n return;\n }\n\n // All other routes are gated — silently return 503 so the UI fails gracefully.\n if (!jegEnabled) {\n res.setHeader('Cache-Control', 'no-store');\n res\n .status(503)\n .json({ error: 'JEG not configured for this deployment.' });\n return;\n }\n\n if (!gen3Endpoint) {\n res.status(503).json({ error: 'GEN3_ENDPOINT is not configured.' });\n return;\n }\n\n // --- Auth: host-injected extractor first, minimal fallback for dev/standalone ---\n const jwt = config.getToken\n ? config.getToken(req)\n : extractTokenFallback(req);\n\n if (!jwt) {\n res.status(401).json({ error: 'Authentication required.' });\n return;\n }\n\n if (!route) {\n res.status(404).json({ error: 'Route not found.' });\n return;\n }\n\n // Extract sub claim for REMOTE_USER — Ambassador already verified the signature.\n const claims = decodeJwtClaims(jwt);\n const rawUsername =\n claims?.sub ??\n claims?.preferred_username ??\n claims?.username ??\n 'unknown';\n const username: string =\n typeof rawUsername === 'string' ? rawUsername : 'unknown';\n\n // Strip CRLF to prevent HTTP header injection (defense-in-depth)\n const safeJwt = jwt.replace(/[\\r\\n]/g, '');\n const safeUsername = username.replace(/[\\r\\n]/g, '');\n\n const ambassadorHeaders: Record<string, string> = {\n Authorization: `Bearer ${safeJwt}`,\n REMOTE_USER: safeUsername,\n };\n\n // No-store for all control plane responses\n res.setHeader('Cache-Control', 'no-store');\n\n const ctx: RouteContext = {\n req,\n gen3Endpoint,\n fenceUrl,\n kernelSpecPolicy,\n ambassadorHeaders,\n jwt,\n username,\n sink,\n idleKillDays,\n maxKernelAgeDays,\n };\n\n switch (route.type) {\n case 'kernelspecs':\n return handleKernelSpecs(ctx, res);\n case 'kernels_list':\n return handleKernelsList(ctx, res);\n case 'reap':\n return handleReap(ctx, res);\n case 'kernel_launch':\n return handleKernelLaunch(ctx, res);\n case 'kernel_delete':\n return handleKernelDelete(ctx, route, res);\n case 'kernel_passthrough':\n return handleKernelPassthrough(ctx, route, res);\n default:\n res.status(404).json({ error: 'Route not matched.' });\n }\n };\n}\n","/**\n * Next.js API route for JupyterLite static assets.\n *\n * The handler options are read from a per-commons JSON file:\n *\n * <GEN3_FRONTEND_CONFIGURATION_ROOT>/<GEN3_COMMONS_NAME>/workspaceAssets.json\n *\n * matching the convention used by the rest of the framework's server-side\n * configuration (see `FilesystemContent` / `GEN3_FRONTEND_CONFIGURATION_ROOT`).\n * The file is optional — DEFAULT_OPTIONS below is used when it is absent or\n * unreadable, so a bad config never takes down the whole assets route.\n *\n * The upstream handler is built lazily on first request rather than at import\n * time: `createWorkspaceAssetsHandler` recursively walks both tier asset trees\n * when constructed, and this module is imported transitively by\n * `next.config.js` (via `@gen3/workspaces/server`) where that I/O is wasted.\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport fs from 'fs';\nimport nodePath from 'path';\nimport { GEN3_COMMONS_NAME } from '@gen3/core';\nimport {\n createWorkspaceAssetsHandler,\n type WorkspaceAssetsHandlerOptions,\n} from '../server/workspaceAssetsHandler';\n\nconst CONFIG_ROOT = process.env.GEN3_FRONTEND_CONFIGURATION_ROOT || './config/';\nconst CONFIG_FILENAME = 'workspaceAssets.json';\n\nconst DEFAULT_OPTIONS: WorkspaceAssetsHandlerOptions = {\n // Route JupyterLite remote-mode kernel WebSocket traffic through revproxy's\n // /lw-workspace/proxy/ nginx block → ambassador-service (ExternalName → Emissary)\n // → JEG. Next.js API routes cannot handle WebSocket upgrades, so we must\n // bypass them and use the nginx path that has allow_upgrade + long timeouts.\n gatewayBaseUrl: '/lw-workspace/proxy/',\n // Route all kernel ops through jeg-proxy so JupyterLite sees merged Python3\n // (container) + JEG GPU kernelspecs. The proxy routes Python3 kernel\n // launches/channels to the container; GPU kernel launches are gated (403)\n // with a message to use the Kernel Panel.\n remoteKernelsPath: '/lw-workspace/proxy/jeg-proxy',\n // The remote tier attaches to a real kernel gateway, so JupyterLite's\n // in-browser Pyodide kernel must not be offered alongside it.\n additionalDisabledExtensions: [\n '@jupyterlite/pyodide-kernel-extension:kernel',\n ],\n appName: GEN3_COMMONS_NAME,\n};\n\nconst STRING_OPTIONS = [\n 'gatewayBaseUrl',\n 'assetRoot',\n 'appName',\n 'faviconUrl',\n 'pageTitle',\n 'remoteKernelsPath',\n 'fullThemesUrl',\n] as const satisfies ReadonlyArray<keyof WorkspaceAssetsHandlerOptions>;\n\nfunction configFilePath(): string {\n return nodePath.resolve(\n process.cwd(),\n CONFIG_ROOT,\n GEN3_COMMONS_NAME,\n CONFIG_FILENAME,\n );\n}\n\n/**\n * Pick and type-check the known option keys. Unknown keys are ignored so a\n * config file can carry extra metadata without reaching the factory,\n * and a wrong-typed value falls back to its default instead of throwing.\n */\nfunction parseOptions(raw: unknown): WorkspaceAssetsHandlerOptions {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n console.warn(\n `[workspace-assets] ${CONFIG_FILENAME} is not a JSON object; using defaults.`,\n );\n return DEFAULT_OPTIONS;\n }\n\n const source = raw as Record<string, unknown>;\n const parsed: WorkspaceAssetsHandlerOptions = {};\n\n for (const key of STRING_OPTIONS) {\n const value = source[key];\n if (value === undefined) continue;\n if (typeof value === 'string') {\n parsed[key] = value;\n } else {\n console.warn(\n `[workspace-assets] ignoring ${key}: expected a string, got ${typeof value}.`,\n );\n }\n }\n\n const extensions = source.additionalDisabledExtensions;\n\n // oxlint-disable-next-line no-console\n console.log(\n 'additional disabled extensions',\n source.additionalDisabledExtensions,\n );\n if (extensions !== undefined) {\n if (\n Array.isArray(extensions) &&\n extensions.every((entry) => typeof entry === 'string')\n ) {\n parsed.additionalDisabledExtensions = extensions;\n } else {\n console.warn(\n '[workspace-assets] ignoring additionalDisabledExtensions: expected an array of strings.',\n );\n }\n }\n\n // oxlint-disable-next-line no-console\n console.log('parsed options', parsed);\n\n return { ...DEFAULT_OPTIONS, ...parsed };\n}\n\nfunction loadOptions(): WorkspaceAssetsHandlerOptions {\n const file = configFilePath();\n try {\n return parseOptions(JSON.parse(fs.readFileSync(file, 'utf-8')));\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n console.warn(\n `[workspace-assets] could not read ${file} (${reason}); using defaults.`,\n );\n return DEFAULT_OPTIONS;\n }\n}\n\nlet upstreamHandler:\n ReturnType<typeof createWorkspaceAssetsHandler> | undefined;\nlet loadedConfigMtimeMs: number | undefined;\n\n/** mtime of the config file, or undefined when it does not exist. */\nfunction configMtimeMs(): number | undefined {\n try {\n return fs.statSync(configFilePath()).mtimeMs;\n } catch {\n return undefined;\n }\n}\n\nfunction getUpstreamHandler(): ReturnType<typeof createWorkspaceAssetsHandler> {\n if (process.env.NODE_ENV === 'development') {\n // Rebuild when the config file changes so edits don't need a dev-server\n // restart. Only the cheap stat runs per request — the expensive asset walk\n // happens on the first request and then only after a real config change.\n const mtimeMs = configMtimeMs();\n if (upstreamHandler && mtimeMs !== loadedConfigMtimeMs) {\n upstreamHandler = undefined;\n }\n loadedConfigMtimeMs = mtimeMs;\n }\n\n if (!upstreamHandler) {\n upstreamHandler = createWorkspaceAssetsHandler(loadOptions());\n }\n return upstreamHandler;\n}\n\nexport default function handler(req: NextApiRequest, res: NextApiResponse) {\n return getUpstreamHandler()(req, res);\n}\n","import type { NextApiRequest, NextApiResponse } from 'next';\nimport { getCookie } from 'cookies-next';\n\n// Allowed path prefixes — keeps proxying scoped to the Jupyter Gateway API surface\nconst ALLOWED_PREFIXES = ['/api/kernels', '/api/sessions', '/api/kernelspecs'];\n\nfunction buildUpstreamPath(segments: string[]): string {\n const clean = segments\n .filter(Boolean)\n .map((s) => s.replace(/^\\/+|\\/+$/g, ''));\n\n if (clean.some((s) => s === '..' || s === '.')) {\n throw new Error('Invalid path segment');\n }\n\n return `/${clean.join('/')}`;\n}\n\nfunction isAllowedPath(path: string): boolean {\n return ALLOWED_PREFIXES.some(\n (prefix) => path === prefix || path.startsWith(`${prefix}/`),\n );\n}\n\nfunction buildQueryString(\n rawUrl: string | undefined,\n excludeKey: string,\n): string {\n if (!rawUrl) return '';\n const queryPart = rawUrl.split('?')[1];\n if (!queryPart) return '';\n\n const params = new URLSearchParams(queryPart);\n params.delete(excludeKey);\n\n const result = params.toString();\n return result ? `?${result}` : '';\n}\n\nfunction readBody(req: NextApiRequest): Promise<Buffer | undefined> {\n return new Promise((resolve, reject) => {\n if (!req.method || ['GET', 'HEAD'].includes(req.method.toUpperCase())) {\n resolve(undefined);\n return;\n }\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer | string) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n req.on('end', () =>\n resolve(chunks.length ? Buffer.concat(chunks) : undefined),\n );\n req.on('error', reject);\n });\n}\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse,\n) {\n const gatewayUrl = process.env.JUPYTER_GATEWAY_URL;\n\n if (!gatewayUrl) {\n res.status(500).json({ error: 'JUPYTER_GATEWAY_URL is not configured' });\n return;\n }\n\n const gatewayBase = gatewayUrl.replace(/\\/+$/, '');\n\n const actionSegments = Array.isArray(req.query.action)\n ? req.query.action\n : req.query.action\n ? [req.query.action]\n : [];\n\n let upstreamPath: string;\n try {\n upstreamPath = buildUpstreamPath(actionSegments);\n } catch {\n res.status(400).json({ error: 'Invalid path' });\n return;\n }\n\n if (!isAllowedPath(upstreamPath)) {\n res.status(403).json({ error: 'Forbidden path' });\n return;\n }\n\n const queryString = buildQueryString(req.url, 'action');\n const targetUrl = `${gatewayBase}${upstreamPath}${queryString}`;\n\n const forwardHeaders = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (!value) continue;\n const lower = key.toLowerCase();\n if (\n lower === 'host' ||\n lower === 'content-length' ||\n lower === 'transfer-encoding'\n )\n continue;\n forwardHeaders.set(key, Array.isArray(value) ? value.join(',') : value);\n }\n\n // Inject server-side JEG token — overrides any client-supplied auth header.\n // This ensures calls from JupyterLite's own serverconnection.js are also authenticated.\n if (process.env.NODE_ENV === 'development') {\n // NOTE: This cookie can only be accessed from the client side\n // in development mode. Otherwise, the cookie is set as httpOnly\n const accessToken = getCookie('credentials_token');\n if (accessToken) {\n forwardHeaders.set('Authorization', `Bearer ${accessToken}`);\n }\n }\n\n let body: Buffer | undefined;\n try {\n body = await readBody(req);\n } catch {\n res.status(500).json({ error: 'Failed to read request body' });\n return;\n }\n\n if (body) {\n forwardHeaders.set('content-length', String(body.byteLength));\n }\n\n let upstream: Response;\n try {\n upstream = await fetch(targetUrl, {\n method: req.method,\n headers: forwardHeaders,\n body: body ? new Uint8Array(body) : undefined,\n signal: AbortSignal.timeout(30_000),\n });\n } catch (err) {\n const isTimeout = err instanceof Error && err.name === 'TimeoutError';\n res.status(isTimeout ? 504 : 502).json({\n error: isTimeout ? 'Gateway timeout' : 'Gateway unreachable',\n });\n return;\n }\n\n res.status(upstream.status);\n upstream.headers.forEach((value, key) => {\n const lower = key.toLowerCase();\n if (\n lower === 'transfer-encoding' ||\n lower === 'content-type' ||\n lower === 'content-security-policy'\n )\n return;\n res.setHeader(key, value);\n });\n\n const upstreamContentType = upstream.headers.get('content-type') || '';\n const safeContentType = /html|xml|svg/i.test(upstreamContentType)\n ? 'text/plain; charset=utf-8'\n : upstreamContentType || 'application/octet-stream';\n res.setHeader('Content-Type', safeContentType);\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('Content-Security-Policy', \"default-src 'none'; sandbox\");\n res.setHeader('Content-Disposition', 'attachment');\n\n if (upstream.body) {\n const reader = upstream.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } finally {\n reader.releaseLock();\n }\n res.end();\n } else {\n res.end();\n }\n}\n\nexport const config = { api: { bodyParser: false } };\n","// Kernel lifecycle proxy — billing gate + Fence credential injection.\n// Browser never sees JEG URL or raw kernel spec names.\n// POST /kernels calls Fence /credentials/cdis first — if it fails, no kernel is launched.\n// getToken reuses this app's cookie extraction — no JWT reinvention.\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { createKernelProxyHandler } from '../server/kernelLifecycleProxy';\nimport { getAccessToken } from '@gen3/frontend/server';\nimport { GEN3_FENCE_API } from '@gen3/core/server';\nimport { JEG_SERVICE_API } from '../constants';\nimport { GEN3_FENCE_SERVICE } from '@gen3/core';\n\nconst inCluster = Boolean(process.env.KUBERNETES_SERVICE_HOST);\nconst defaultGen3Endpoint = inCluster\n ? JEG_SERVICE_API\n : '/lw-workspace/proxy/jeg-panel';\nconst defaultFenceUrl = inCluster ? GEN3_FENCE_SERVICE : GEN3_FENCE_API;\n\nconst gen3Endpoint = process.env.JEG_SERVICE_API ?? defaultGen3Endpoint;\nconst fenceUrl = defaultFenceUrl;\n\nif (!gen3Endpoint) {\n console.warn(\n '[workspace-kernel] JEG_SERVICE_API is not set and not running in-cluster — kernel proxy will likely fail',\n );\n}\nif (!fenceUrl) {\n console.warn(\n '[workspace-kernel] FENCE_URL is not set and not running in-cluster — credential injection will likely fail',\n );\n}\n\nlet policy: Record<string, unknown> = {};\nif (process.env.KERNEL_SPEC_POLICY) {\n try {\n policy = JSON.parse(process.env.KERNEL_SPEC_POLICY);\n } catch (err) {\n throw new Error(\n `[workspace-kernel] KERNEL_SPEC_POLICY is not valid JSON: ${(err as Error).message}`,\n );\n }\n}\n\nconst upstreamHandler = createKernelProxyHandler({\n gen3Endpoint,\n fenceUrl,\n kernelSpecPolicy: policy,\n jegEnabled: process.env.ENABLE_JEG === 'true',\n getToken: (req) => {\n const token = getAccessToken(req.headers['cookie'] ?? '') ?? null;\n if (!token) {\n console.warn(\n '[workspace-kernel] No access token found in request cookies',\n );\n }\n return token;\n },\n});\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse,\n) {\n try {\n await upstreamHandler(req, res);\n } catch (err) {\n console.error('[workspace-kernel] Upstream handler threw:', err);\n if (!res.headersSent) {\n res.status(502).json({ error: 'Bad gateway' });\n }\n return;\n }\n}\n\nexport const config = { api: { bodyParser: false } };\n","/**\n * createHatcheryProxyHandler — server-side Next.js API route handler for Hatchery\n * micro-container lifecycle (launch, terminate, status, options).\n *\n * Security properties:\n * - Strict allowlist: only /options, /status, /launch, /terminate are proxied.\n * - All other paths return 404 — Hatchery internals are never reachable.\n * - JWT forwarded as Bearer; user identity set as REMOTE_USER for server-side isolation.\n * - `id` query param sanitized against SAFE_ID_RE (SSRF and injection prevention).\n *\n * Token extraction:\n * Pass getToken to reuse the host app's existing cookie logic (strongly recommended).\n * In gen3-vectis this is getAccessToken from lib/auth/getLoginStatus.\n * Without getToken, a minimal Bearer/cookie fallback is used (dev/standalone only).\n * Ambassador performs RS256 verification before any request reaches Next.js.\n *\n * Usage (src/pages/api/workspace/hatchery/[...action].ts — generated by bin/init.mjs):\n * import { createHatcheryProxyHandler } from '@gen3/jupyter-workspaces/server';\n * import { getAccessToken } from '../../lib/auth/getLoginStatus';\n * export default createHatcheryProxyHandler({\n * hatcheryUrl: process.env.HATCHERY_URL,\n * getToken: (req) => getAccessToken(req.headers['cookie'] ?? '') ?? null,\n * });\n * export const config = { api: { bodyParser: false } };\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport {\n createProxyRequest,\n decodeJwtClaims,\n extractTokenFallback,\n} from './utils';\n\nexport interface HatcheryProxyConfig {\n /** Internal URL of the Hatchery service, e.g. http://hatchery.hatchery.svc:8000 */\n hatcheryUrl: string | undefined;\n /**\n * Token extractor injected by the host application.\n * In gen3-vectis: `(req) => getAccessToken(req.headers['cookie'] ?? '') ?? null`\n * When omitted, a minimal Bearer-header/cookie fallback is used (dev/standalone only).\n * Ambassador has already done RS256 verification — this is extraction only.\n */\n getToken?: (req: NextApiRequest) => string | null;\n}\n\ntype HatcheryRoute =\n | { method: 'GET'; path: '/options' }\n | { method: 'GET'; path: '/status' }\n | { method: 'POST'; path: '/launch' }\n | { method: 'POST'; path: '/terminate' };\n\nconst SAFE_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;\n\nfunction resolveHatcheryRoute(\n method: string,\n actionSegments: string[],\n): HatcheryRoute | null {\n const action = actionSegments[0] || '';\n const routes: Record<string, HatcheryRoute> = {\n 'GET:options': { method: 'GET', path: '/options' },\n 'GET:status': { method: 'GET', path: '/status' },\n 'POST:launch': { method: 'POST', path: '/launch' },\n 'POST:terminate': { method: 'POST', path: '/terminate' },\n };\n return routes[`${method}:${action}`] ?? null;\n}\n\nconst ALLOWED_HATCHERY_URLS = [\n '/lw-workspace',\n 'http://hatchery-service.gen3.svc.cluster.local',\n];\n\nexport function createHatcheryProxyHandler(config: HatcheryProxyConfig) {\n return async function hatcheryProxyHandler(\n req: NextApiRequest,\n res: NextApiResponse,\n ): Promise<void> {\n const hatcheryUrl = config.hatcheryUrl;\n\n if (!hatcheryUrl) {\n res.status(503).json({\n error: 'Hatchery service is not configured (HATCHERY_URL missing).',\n });\n return;\n }\n\n if (!ALLOWED_HATCHERY_URLS.includes(hatcheryUrl)) {\n res.status(503).json({ error: 'Hatchery service URL is misconfigured.' });\n return;\n }\n\n let parsedHatcheryUrl: URL;\n try {\n parsedHatcheryUrl = new URL(hatcheryUrl);\n } catch {\n res.status(503).json({ error: 'Hatchery service URL is misconfigured.' });\n return;\n }\n if (\n parsedHatcheryUrl.protocol !== 'http:' &&\n parsedHatcheryUrl.protocol !== 'https:'\n ) {\n res.status(503).json({ error: 'Hatchery service URL is misconfigured.' });\n return;\n }\n\n // --- Auth: host-injected extractor first, minimal fallback for dev/standalone ---\n const jwt = config.getToken\n ? config.getToken(req)\n : extractTokenFallback(req);\n if (!jwt) {\n res.status(401).json({ error: 'Authentication required.' });\n return;\n }\n\n // Validate JWT format to prevent injection attacks\n // JWT should be three base64url-encoded segments separated by dots\n const JWT_FORMAT_RE = /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\n if (!JWT_FORMAT_RE.test(jwt)) {\n console.error('[hatcheryProxy] Invalid JWT format detected');\n res.status(401).json({ error: 'Invalid authentication token format.' });\n return;\n }\n\n // Additional length check to prevent extremely long tokens\n if (jwt.length > 8192) {\n console.error('[hatcheryProxy] JWT exceeds maximum length');\n res.status(401).json({ error: 'Authentication token too long.' });\n return;\n }\n\n // Extract sub claim for REMOTE_USER — Ambassador already verified the signature.\n const claims = decodeJwtClaims(jwt);\n const rawUsername =\n claims?.sub ?? claims?.preferred_username ?? claims?.username;\n const username: string | undefined =\n typeof rawUsername === 'string' ? rawUsername : undefined;\n if (!username) {\n res\n .status(401)\n .json({ error: 'Unable to determine username from token.' });\n return;\n }\n // Strip CRLF to prevent HTTP header injection (defense-in-depth)\n const safeJwt = jwt.replace(/[\\r\\n]/g, '');\n const safeUsername = username.replace(/[\\r\\n]/g, '');\n\n // --- Route resolution ---\n const actionSegments = (req.query.action as string[]) || [];\n const route = resolveHatcheryRoute(req.method || '', actionSegments);\n if (!route) {\n res.status(404).json({ error: 'Route not found.' });\n return;\n }\n\n // --- Sanitize launch/terminate id param (SSRF prevention) ---\n let queryString = '';\n if (route.path === '/launch' || route.path === '/terminate') {\n const id = (req.query.id as string) || '';\n if (id) {\n if (!SAFE_ID_RE.test(id)) {\n res.status(400).json({ error: 'Invalid container identifier.' });\n return;\n }\n queryString = `?id=${encodeURIComponent(id)}`;\n }\n } else if (route.path === '/status' || route.path === '/options') {\n // Pass id through safely for status/options\n const id = (req.query.id as string) || '';\n if (id) {\n if (!SAFE_ID_RE.test(id)) {\n res.status(400).json({ error: 'Invalid container identifier.' });\n return;\n }\n queryString = `?id=${encodeURIComponent(id)}`;\n }\n }\n\n const hatcheryBase = `${parsedHatcheryUrl.origin}${parsedHatcheryUrl.pathname.replace(/\\/$/, '')}`;\n const targetUrl = `${hatcheryBase}${route.path}${queryString}`;\n\n await createProxyRequest({\n req,\n res,\n targetUrl,\n method: route.method,\n extraHeaders: {\n Authorization: `Bearer ${safeJwt}`,\n REMOTE_USER: safeUsername,\n remote_user: safeUsername,\n },\n // Hatchery doesn't need a body for GET routes\n forwardBody: route.method === 'POST',\n });\n };\n}\n","// Hatchery proxy — strict allowlist: /options, /status, /launch, /terminate\n// Injects Authorization + REMOTE_USER headers; sanitizes id param (SSRF prevention).\n// getToken reuses this app's cookie extraction — no JWT reinvention.\nimport { createHatcheryProxyHandler } from '../server/hatcheryProxy';\nimport { getAccessToken } from '@gen3/frontend/server';\nimport type { NextApiRequest, NextApiResponse } from 'next';\n\nconst defaultHatcheryUrl = process.env.KUBERNETES_SERVICE_HOST\n ? 'http://hatchery-service.gen3.svc.cluster.local'\n : '/lw-workspace';\n\nconst upstreamHandler = createHatcheryProxyHandler({\n hatcheryUrl: defaultHatcheryUrl,\n getToken: (req) => getAccessToken(req.headers['cookie'] ?? '') ?? null,\n});\n\n// oxlint-disable-next-line no-unused-vars\nfunction decodeJwtUsername(jwt: string): string {\n try {\n const payload = jwt.split('.')[1];\n const claims = JSON.parse(\n Buffer.from(payload, 'base64url').toString('utf8'),\n ) as Record<string, unknown>;\n const raw = claims.sub ?? claims.preferred_username ?? claims.username;\n return typeof raw === 'string'\n ? raw\n : `<non-string:${JSON.stringify(raw)}>`;\n } catch {\n return '<decode-error>';\n }\n}\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse,\n) {\n // oxlint-disable-next-line no-unused-vars\n const action = req.query.action?.[0];\n\n // Intercept res.send to capture response body for logging\n // oxlint-disable-next-line no-unused-vars\n let capturedBody = '';\n const originalSend = res.send.bind(res) as typeof res.send;\n res.send = (body: unknown) => {\n capturedBody = (\n typeof body === 'string' ? body : JSON.stringify(body)\n ).slice(0, 300);\n return originalSend(body);\n };\n\n await upstreamHandler(req, res);\n}\n\nexport const config = { api: { bodyParser: false } };\n"],"names":["GEN3_HATCHERY_API","GEN3_WORKSPACE_API","process","env","GEN3_KERNEL_API","GEN3_API","JEG_GATEWAY_API","JEG_SERVICE_API","MAX_FILE_SIZE_BYTES","ALLOWED_TIERS","Set","SAFE_SEGMENT_RE","MIME_TYPES","DEFAULT_FULL_THEMES_URL","REMOTE_DISABLED_EXTENSIONS","ASSETS_ROOT_PATH","JUPYTER_ASSETS_ROOT_PATH","defaultAssetRoot","startsWith","nodePath","join","cwd","DEFAULT_REMOTE_BRANDING","appName","faviconUrl","escapeHtml","text","replace","replaceTitle","html","branding","title","pageTitle","resolveOrigin","req","forwardedProto","Array","isArray","headers","forwardedHost","hostHeader","host","refererHeader","referer","resolvedHost","trim","resolvedProto","String","refererUrl","URL","includes","protocol","proto","injectRemoteConfig","config","gatewayBaseUrl","disabledExtensions","fullThemesUrl","remoteKernelsPath","absoluteGatewayBase","accessToken","undefined","NODE_ENV","getCookie","configData","remoteBaseUrl","remoteToken","exposeAppInBrowser","remoteKernelsBaseUrl","result","_match","openTag","existingJson","closeTag","existing","JSON","parse","merged","combined","stringify","injectBranding","error","Error","console","warn","message","createWorkspaceAssetsHandler","options","JUPYTER_GATEWAY_BASE_URL","assetRoot","log","additionalDisabledExtensions","remoteInjectionConfig","walkDir","dir","set","entry","fs","readdirSync","withFileTypes","full","name","isDirectory","add","allowedFilesByTier","free","remote","tier","resolve","handler","res","path","pathSegments","query","has","status","end","segments","tierRoot","safeSegments","seg","test","push","basename","allowedFiles","candidatePath","candidateIndex","filePath","ext","extname","toLowerCase","contentType","isBuildAsset","setHeader","cookies","encodeURIComponent","isRemoteLabHtml","readFileSync","injected","send","isHtmlResponse","stat","statSync","size","stream","createReadStream","on","pipe","DEFAULT_WORKSPACE_ROUTES","withJupyterWorkspaces","nextConfig","workspaceRoutes","transpilePackages","filter","pkg","webpack","ctx","alias","react","dirname","require","rewrites","isDev","gatewayProxyUrl","GATEWAY_PROXY_URL","gatewayRewrite","source","destination","beforeFiles","coopCoepHeaders","map","route","key","value","extractTokenFallback","auth","slice","cookie","m","match","decodeURIComponent","MAX_JWT_LENGTH","decodeJwtClaims","jwt","length","parts","split","padded","padEnd","Math","ceil","Buffer","from","toString","createProxyRequest","targetUrl","method","extraHeaders","forwardBody","body","buf","bufferBody","err","statusCode","msg","json","upRes","fetch","signal","AbortSignal","timeout","get","errBody","catch","responseBody","MAX_BODY_BYTES","Promise","reject","chunks","total","chunk","destroy","Object","assign","concat","defaultBillingSink","event","stdout","write","type","EMPTY_FENCE_CREDS","key_id","api_key","fetchFenceCreds","fenceUrl","parsedFenceUrl","response","fetchFence","endpoint","Authorization","data","filterAndAnnotateSpecs","raw","policy","allowedSpecs","costPerHour","displayNames","nodeType","filteredSpecs","specName","rawSpec","kernelspecs","spec","display_name","metadata","filteredDefault","default","readBody","buildAmbassadorUrl","gen3Endpoint","kernelPath","base","parsed","origin","pathname","KERNEL_ID_RE","SIMPLE_ROUTES","Map","resolveKernelRoute","actionSegments","seg1","seg2","kernelId","rest","errMsg","handleKernelSpecs","upstream","ambassadorHeaders","ok","statusText","rawSpecs","kernelSpecPolicy","handleKernelsList","handleReap","listUpstream","kernelList","listRes","now","Date","idleKillMins","idleKillDays","maxAgeMins","maxKernelAgeDays","reaped","errors","kernel","id","lastActivity","last_activity","getTime","idleMins","Infinity","deleteUpstream","sink","username","action","costTier","timestamp","toISOString","handleKernelLaunch","fenceCreds","rawBody","launchBody","kernelSpec","enrichedBody","GEN3_API_KEY_ID","GEN3_API_KEY_SECRET","NAMESPACE","GEN3_ENDPOINT","launchTimestamp","launchRes","kernelData","handleKernelDelete","handleKernelPassthrough","ALLOWED_FENCE_URLS","GEN3_FENCE_SERVICE","GEN3_FENCE_API","ALLOWED_JEG_URLS","createKernelProxyHandler","billingSink","jegEnabled","kernelLifecycleProxyHandler","rawAction","s","enabled","getToken","claims","rawUsername","sub","preferred_username","safeJwt","safeUsername","REMOTE_USER","CONFIG_ROOT","GEN3_FRONTEND_CONFIGURATION_ROOT","CONFIG_FILENAME","DEFAULT_OPTIONS","GEN3_COMMONS_NAME","STRING_OPTIONS","configFilePath","parseOptions","extensions","every","loadOptions","file","reason","upstreamHandler","loadedConfigMtimeMs","configMtimeMs","mtimeMs","getUpstreamHandler","ALLOWED_PREFIXES","buildUpstreamPath","clean","Boolean","some","isAllowedPath","prefix","buildQueryString","rawUrl","excludeKey","queryPart","params","URLSearchParams","delete","toUpperCase","isBuffer","gatewayUrl","JUPYTER_GATEWAY_URL","gatewayBase","upstreamPath","queryString","url","forwardHeaders","Headers","entries","lower","byteLength","Uint8Array","isTimeout","forEach","upstreamContentType","safeContentType","reader","getReader","done","read","releaseLock","inCluster","KUBERNETES_SERVICE_HOST","defaultGen3Endpoint","defaultFenceUrl","KERNEL_SPEC_POLICY","ENABLE_JEG","token","getAccessToken","headersSent","SAFE_ID_RE","resolveHatcheryRoute","routes","ALLOWED_HATCHERY_URLS","createHatcheryProxyHandler","hatcheryProxyHandler","hatcheryUrl","parsedHatcheryUrl","JWT_FORMAT_RE","hatcheryBase","remote_user","defaultHatcheryUrl","originalSend","bind","capturedBody"],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sources":["../../../src/constants.ts","../../../src/server/utils.ts","../../../src/server/workspaceAssetsHandler.ts","../../../src/server/withJupyterWorkspaces.ts","../../../src/server/kernelLifecycleProxy.ts","../../../src/api/workspaceAssetsApi.ts","../../../src/api/workspaceGatewayApiHandler.ts","../../../src/api/kernelApiHandler.ts","../../../src/server/hatcheryProxy.ts","../../../src/api/hatcheryApiHandler.ts"],"sourcesContent":["import { GEN3_API, GEN3_WORKSPACE_API } from '@gen3/core';\n\n// TODO: migrate this to @gen3/core\n\nexport const GEN3_HATCHERY_API =\n GEN3_WORKSPACE_API || '/workspace-api/workspace/hatchery'; // get replaced by revproxy\n\nexport const GEN3_KERNEL_API =\n process.env.GEN3_KERNEL_API || `${GEN3_API}/lw-workspace/proxy/jeg-panel/api`;\n\nexport const GEN3_JEG_GATEWAY_API =\n process.env.JEG_GATEWAY_API || `${GEN3_API}/lw-workspace/proxy/jeg-panel/api`;\n\n// TODO: resolve this with @gen3/core\nexport const GEN3_WORKSPACES_API =\n GEN3_WORKSPACE_API || `${GEN3_API}/lw-workspace`;\n\nexport const JEG_SERVICE_API =\n 'http://jupyter-enterprise-gateway.jupyter-pods.svc.cluster.local:8888';\n","/**\n * Shared HTTP proxy utility for server-side proxy handlers.\n * Streams request body through and forwards response status + body.\n *\n * Also exports two token helpers used by the proxy factories:\n * - extractTokenFallback: minimal cookie/header extraction used when the host\n * app has not injected its own getToken (standalone / test use).\n * - decodeJwtClaims: base64url decode of the JWT payload for REMOTE_USER header.\n * Crypto verification is Ambassador's job — we only need the sub/username claim.\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\n\n/**\n * Minimal JWT extraction fallback — used only when the host app does not inject\n * its own getToken. Prefers Authorization: Bearer, then access_token cookie.\n * In gen3-vectis production this is never reached — getAccessToken is always wired.\n */\nexport function extractTokenFallback(req: NextApiRequest): string | null {\n const auth = req.headers['authorization'];\n if (typeof auth === 'string' && auth.startsWith('Bearer ')) {\n return auth.slice(7).trim() || null;\n }\n const cookie = req.headers['cookie'] ?? '';\n const m = cookie.match(/(?:^|;\\s*)access_token=([^;]+)/);\n return m ? decodeURIComponent(m[1]).trim() || null : null;\n}\n\n/**\n * Decode JWT payload claims without cryptographic verification.\n * Ambassador has already verified the RS256 signature — we just need the sub claim\n * to set the REMOTE_USER header for per-user isolation enforcement downstream.\n */\n// Maximum JWT string length accepted before base64 decoding.\n// GA4GH RAS Passport JWTs embed multiple signed Visa JWTs as claims, so the\n// outer passport can easily exceed 8 KiB (50 visas × ~2 KB each ≈ 136 KB encoded).\n// 512 KiB covers the most complex real-world passports while still guarding against\n// crafted JWTs designed to exhaust server memory. Ambassador has already verified\n// the RS256 signature — this cap only defends the local base64/JSON decode step.\nconst MAX_JWT_LENGTH = 524288; // 512 KiB\n\nexport function decodeJwtClaims(jwt: string): Record<string, unknown> | null {\n if (jwt.length > MAX_JWT_LENGTH) return null;\n try {\n const parts = jwt.split('.');\n if (parts.length < 2) return null;\n const padded = parts[1]\n .replace(/-/g, '+')\n .replace(/_/g, '/')\n .padEnd(Math.ceil(parts[1].length / 4) * 4, '=');\n return JSON.parse(Buffer.from(padded, 'base64').toString('utf8')) as Record<\n string,\n unknown\n >;\n } catch {\n return null;\n }\n}\n\nexport interface ProxyRequestOptions {\n req: NextApiRequest;\n res: NextApiResponse;\n targetUrl: string;\n method: 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH';\n extraHeaders?: Record<string, string>;\n /** Whether to stream the incoming request body to the target. */\n forwardBody?: boolean;\n}\n\nexport async function createProxyRequest({\n req,\n res,\n targetUrl,\n method,\n extraHeaders = {},\n forwardBody = false,\n}: ProxyRequestOptions): Promise<void> {\n const headers: Record<string, string> = {\n ...extraHeaders,\n };\n if (\n forwardBody &&\n (method === 'POST' || method === 'PUT' || method === 'PATCH')\n ) {\n headers['Content-Type'] ??= 'application/json';\n }\n\n let body: BodyInit | undefined;\n if (\n forwardBody &&\n (method === 'POST' || method === 'PUT' || method === 'PATCH')\n ) {\n let buf: Buffer;\n try {\n buf = await bufferBody(req);\n } catch (err) {\n const statusCode = (err as { statusCode?: number }).statusCode ?? 400;\n const msg = err instanceof Error ? err.message : 'Bad request';\n res.status(statusCode).json({ error: msg });\n return;\n }\n // Node.js Buffer is a Uint8Array subclass; cast to silence DOM BodyInit mismatch\n body = buf as unknown as BodyInit;\n if (buf.length > 0) {\n headers['Content-Length'] = String(buf.length);\n }\n }\n\n let upRes: Response;\n try {\n upRes = await fetch(targetUrl, {\n method,\n headers,\n body,\n signal: AbortSignal.timeout(30_000),\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n res.status(502).json({ error: `Upstream unreachable: ${msg}` });\n return;\n }\n\n // Forward status and content-type\n const contentType = upRes.headers.get('content-type') || 'application/json';\n res.setHeader('Content-Type', contentType);\n\n if (upRes.status === 204 || upRes.status === 304) {\n res.status(upRes.status).end();\n return;\n }\n\n // Do not forward raw upstream error bodies — they may contain stack traces or\n // internal hostnames. Log them server-side (CloudWatch) and return a generic message.\n if (upRes.status >= 500) {\n const errBody = await upRes.text().catch(() => '');\n console.error(\n '[proxy] upstream %d from %s: %s',\n upRes.status,\n targetUrl,\n errBody,\n );\n res.status(502).json({ error: 'Upstream service error.' });\n return;\n }\n\n const responseBody = await upRes.text();\n res.status(upRes.status).send(responseBody);\n}\n\n// Maximum request body size accepted by the proxy (1 MiB).\n// Prevents memory exhaustion from oversized payloads before any business logic runs.\nconst MAX_BODY_BYTES = 1 * 1024 * 1024;\n\nfunction bufferBody(req: NextApiRequest): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let total = 0;\n req.on('data', (chunk: Buffer) => {\n total += chunk.length;\n if (total > MAX_BODY_BYTES) {\n req.destroy();\n reject(\n Object.assign(new Error('Request body too large'), {\n statusCode: 413,\n }),\n );\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n","/**\n * Next.js API route handler factory for serving JupyterLite static assets.\n *\n * Usage (consumer's `src/pages/api/workspace-assets/[tier]/[[...path]].ts`):\n *\n * import { createWorkspaceAssetsHandler } from '@gen3/jupyter-workspaces/server';\n * export default createWorkspaceAssetsHandler();\n *\n * Or with custom config:\n *\n * export default createWorkspaceAssetsHandler({\n * gatewayBaseUrl: '/api/workspace/gateway/',\n * });\n *\n * `workspaceAssetsApi` (this package's default wiring) builds its options from\n * `<GEN3_FRONTEND_CONFIGURATION_ROOT>/<GEN3_COMMONS_NAME>/workspaceAssets.json`,\n * so per-commons branding and gateway routing need no code changes.\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport nodePath from 'path';\nimport fs from 'fs';\nimport http from 'http';\nimport https from 'https';\nimport { getCookie } from 'cookies-next';\nimport { decodeJwtClaims, extractTokenFallback } from './utils';\n\nconst MAX_FILE_SIZE_BYTES = 67108864; // 64 * 1024 * 1024\n\n// ---------- types ----------\n\nexport interface WorkspaceAssetsHandlerOptions {\n /** Gateway base URL injected into remote tier config (default: env JUPYTER_GATEWAY_BASE_URL or '/api/workspace/gateway/') */\n gatewayBaseUrl?: string;\n /**\n * Root directory containing the JupyterLite assets.\n * Default: `<cwd>/node_modules/@gen3/jupyter-workspaces/assets`\n */\n assetRoot?: string;\n /** Additional JupyterLite extensions to disable for the remote tier */\n additionalDisabledExtensions?: string[];\n /** Application name injected into JupyterLite config data and used as <title> override (opt-in branding). */\n appName?: string;\n /** Favicon URL injected into JupyterLite config data (opt-in branding). */\n faviconUrl?: string;\n /**\n * `<title>` override for served JupyterLite HTML. Defaults to `appName` when\n * omitted; set it when the window title should differ from the config-data\n * `appName` JupyterLite reports internally.\n */\n pageTitle?: string;\n /**\n * Token extractor injected by the host application — used to add identity\n * headers (`Authorization`, `REMOTE_USER`, `X-Gen3-User-ID`) when proxying\n * server extension API calls to `serverExtensionProxyPath`.\n *\n * The workspace-proxy checks `X-Gen3-User-ID` / `REMOTE_USER` (injected by\n * nginx in normal traffic) but server-side proxy calls bypass nginx, so these\n * headers must be set explicitly.\n *\n * In gen3-vectis: `(req) => getAccessToken(req.headers['cookie'] ?? '') ?? null`\n * When omitted, `extractTokenFallback` is used (Bearer header → access_token cookie).\n */\n getToken?: (req: NextApiRequest) => string | null;\n /**\n * Origin-relative path used to build the absolute `remoteKernelsBaseUrl`\n * injected into the remote tier (e.g. `/lw-workspace/proxy/jeg-proxy`).\n * The origin is resolved per-request from forwarding headers so JupyterLite\n * does not resolve kernel endpoints relative to the assets route.\n * Omitted → `remoteKernelsBaseUrl` is not injected.\n */\n remoteKernelsPath?: string;\n /** Override for the remote tier's `fullThemesUrl` (default: `/workspace-api/workspace-assets/remote/build/themes`). */\n fullThemesUrl?: string;\n /**\n * Origin-relative path to proxy server extension API calls for the remote tier\n * (e.g. `/lw-workspace/proxy/jeg-proxy`).\n *\n * JupyterLab extensions such as `jupyterlmod` and `jupyter-server-proxy` make REST\n * calls relative to the JupyterLite base URL. Those requests land on this static-file\n * handler and 404 because no matching file exists. When this option is set, requests\n * whose first path segment matches a known extension API prefix are proxied to\n * `{origin}{serverExtensionProxyPath}/{rest}` instead.\n *\n * Omitted → extension API calls fall through to the static file handler (404).\n */\n serverExtensionProxyPath?: string;\n /**\n * Full base URL for proxying server extension API calls, overriding the\n * origin resolved from the incoming request.\n *\n * Use this to target an internal Kubernetes service directly and avoid routing\n * through the ingress (which may use a self-signed certificate).\n * Example: `http://workspace-proxy-service.namespace.svc.cluster.local:8000`\n *\n * When set, the proxy target is built as\n * `{serverExtensionProxyBaseUrl}{serverExtensionProxyPath}/{rest}`\n * instead of `{requestOrigin}{serverExtensionProxyPath}/{rest}`.\n *\n * Omitted → origin is resolved from the incoming request headers (default behaviour).\n */\n serverExtensionProxyBaseUrl?: string;\n}\n\n// ---------- constants ----------\n\nconst ALLOWED_TIERS = new Set(['free', 'remote']);\n\nconst SAFE_SEGMENT_RE = /^@?[A-Za-z0-9._-]+$/;\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.wasm': 'application/wasm',\n '.txt': 'text/plain; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.woff': 'font/woff',\n '.ttf': 'font/ttf',\n '.map': 'application/json; charset=utf-8',\n '.ipynb': 'application/json; charset=utf-8',\n};\n\nconst DEFAULT_FULL_THEMES_URL =\n '/workspace-api/workspace-assets/remote/build/themes';\n\n/**\n * First path segments that identify server extension REST APIs (not static assets).\n * Requests whose first segment matches one of these are proxied to\n * `serverExtensionProxyPath` when that option is configured for the remote tier.\n */\nconst SERVER_EXTENSION_PREFIXES = new Set(['module', 'server-proxy']);\n\nconst REMOTE_DISABLED_EXTENSIONS = [\n '@jupyterlite/services-extension:config-section-manager',\n '@jupyterlite/services-extension:default-drive',\n '@jupyterlite/services-extension:event-manager',\n '@jupyterlite/services-extension:exporters',\n '@jupyterlite/services-extension:kernel-manager',\n '@jupyterlite/services-extension:kernel-client',\n '@jupyterlite/services-extension:kernel-spec-client',\n '@jupyterlite/services-extension:kernel-spec-manager',\n '@jupyterlite/services-extension:kernel-specs',\n '@jupyterlite/services-extension:nbconvert-manager',\n '@jupyterlite/services-extension:session-manager',\n '@jupyterlite/application-extension:service-worker-manager',\n '@jupyterlab/apputils-extension:themes',\n];\n\n// ---------- helpers ----------\n\nconst ASSETS_ROOT_PATH =\n process.env.JUPYTER_ASSETS_ROOT_PATH || '/gen3/jupyter-workspaces/assets';\n\nfunction defaultAssetRoot(): string {\n return ASSETS_ROOT_PATH.startsWith('/')\n ? ASSETS_ROOT_PATH\n : nodePath.join(process.cwd(), ASSETS_ROOT_PATH);\n}\ninterface BrandingConfig {\n appName?: string;\n faviconUrl?: string;\n pageTitle?: string;\n}\n\nconst DEFAULT_REMOTE_BRANDING: BrandingConfig = {\n appName: 'JupyterLite',\n faviconUrl: '/favicon2.ico',\n};\n\n/** Escape characters that are special inside an HTML text node / attribute. */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;');\n}\n\n/**\n * Replace the document title with the configured page title (or app name).\n * Values originate from a server-side config file, but they are escaped so a\n * stray `<` in a commons name cannot break out of the title element.\n */\nfunction replaceTitle(html: string, branding: BrandingConfig): string {\n const title = branding.pageTitle ?? branding.appName;\n if (!title) return html;\n return html.replace(\n /<title>[^<]*<\\/title>/,\n `<title>${escapeHtml(title)}</title>`,\n );\n}\n\n/**\n * Resolve the origin from forwarding headers, with referer fallback.\n * Handles proxies that drop non-standard ports from the Host header.\n */\nfunction resolveOrigin(req: NextApiRequest): { proto: string; host: string } {\n const forwardedProto =\n (Array.isArray(req.headers['x-forwarded-proto'])\n ? req.headers['x-forwarded-proto'][0]\n : req.headers['x-forwarded-proto']) || 'http';\n const forwardedHost = Array.isArray(req.headers['x-forwarded-host'])\n ? req.headers['x-forwarded-host'][0]\n : req.headers['x-forwarded-host'];\n const hostHeader = Array.isArray(req.headers.host)\n ? req.headers.host[0]\n : req.headers.host;\n const refererHeader = Array.isArray(req.headers.referer)\n ? req.headers.referer[0]\n : req.headers.referer;\n\n let resolvedHost = (forwardedHost || hostHeader || '').trim();\n let resolvedProto = String(forwardedProto).trim() || 'http';\n\n if (refererHeader) {\n try {\n const refererUrl = new URL(refererHeader);\n if (!resolvedHost || !resolvedHost.includes(':')) {\n resolvedHost = refererUrl.host;\n }\n if (!resolvedProto) {\n resolvedProto = refererUrl.protocol.replace(':', '');\n }\n } catch {\n // Ignore malformed referer and keep header-derived values.\n }\n }\n\n if (!resolvedHost) {\n resolvedHost = 'localhost:8890';\n }\n\n return { proto: resolvedProto, host: resolvedHost };\n}\n\ninterface RemoteInjectionConfig {\n gatewayBaseUrl: string;\n disabledExtensions: string[];\n fullThemesUrl: string;\n remoteKernelsPath?: string;\n branding?: BrandingConfig;\n}\n\nfunction injectRemoteConfig(\n html: string,\n req: NextApiRequest,\n config: RemoteInjectionConfig,\n): string {\n const {\n gatewayBaseUrl,\n disabledExtensions,\n fullThemesUrl,\n remoteKernelsPath,\n } = config;\n const branding = config.branding ?? DEFAULT_REMOTE_BRANDING;\n\n const { proto, host } = resolveOrigin(req);\n const absoluteGatewayBase = `${proto}://${host}${gatewayBaseUrl}`;\n\n // Inject server-side JEG token — overrides any client-supplied auth header.\n // This ensures calls from JupyterLite's own serverconnection.js are also authenticated.\n\n let accessToken = undefined;\n if (process.env.NODE_ENV === 'development') {\n // NOTE: This cookie can only be accessed from the client side\n // in development mode. Otherwise, the cookie is set as httpOnly\n accessToken = getCookie('credentials_token');\n }\n\n const configData: Record<string, unknown> = {\n remoteBaseUrl: absoluteGatewayBase,\n remoteToken: accessToken,\n disabledExtensions,\n fullThemesUrl,\n // Required so JupyterLab sets window.jupyterapp, which the parent\n // frame uses for polling readiness and attaching remote kernels.\n exposeAppInBrowser: 'true',\n };\n\n if (remoteKernelsPath) {\n // Absolute so JupyterLite does not resolve kernel ops relative to\n // /workspace-api/workspace-assets/remote/. Routing all kernel traffic\n // through jeg-proxy lets JupyterLite see merged container + JEG kernelspecs.\n configData.remoteKernelsBaseUrl = `${proto}://${host}${remoteKernelsPath}`;\n }\n\n if (branding?.appName) configData.appName = branding.appName;\n if (branding?.faviconUrl) configData.faviconUrl = branding.faviconUrl;\n\n const result = html.replace(\n /(<script\\s+id=\"jupyter-config-data\"[^>]*>)\\s*(\\{[^]*?\\})\\s*(<\\/script>)/,\n (_match, openTag: string, existingJson: string, closeTag: string) => {\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(existingJson);\n } catch {\n // empty or malformed — start fresh\n }\n const merged = { ...existing, ...configData };\n if (Array.isArray(existing.disabledExtensions)) {\n const combined = new Set([\n ...(existing.disabledExtensions as string[]),\n ...disabledExtensions,\n ]);\n merged.disabledExtensions = [...combined];\n }\n return `${openTag}${JSON.stringify(merged)}${closeTag}`;\n },\n );\n\n return replaceTitle(result, branding);\n}\n\nfunction injectBranding(html: string, branding: BrandingConfig): string {\n const result = html.replace(\n /(<script\\s+id=\"jupyter-config-data\"[^>]*>)\\s*(\\{[^]*?\\})\\s*(<\\/script>)/,\n (_match, openTag: string, existingJson: string, closeTag: string) => {\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(existingJson);\n } catch (error: unknown) {\n // empty or malformed — start fresh\n if (error instanceof Error) {\n console.warn('Failed to parse existing JSON', error.message);\n } else {\n console.warn('Failed to parse existing JSON', error);\n }\n }\n if (branding.appName) existing.appName = branding.appName;\n if (branding.faviconUrl) existing.faviconUrl = branding.faviconUrl;\n return `${openTag}${JSON.stringify(existing)}${closeTag}`;\n },\n );\n\n return replaceTitle(result, branding);\n}\n\n// ---------- server-extension proxy ----------\n\nfunction readBody(req: NextApiRequest): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => chunks.push(chunk));\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\nasync function proxyServerExtension(\n req: NextApiRequest,\n res: NextApiResponse,\n targetUrl: string,\n getToken?: (req: NextApiRequest) => string | null,\n): Promise<void> {\n const forwardHeaders: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(req.headers)) {\n if (!value) continue;\n const lower = key.toLowerCase();\n if (\n lower === 'host' ||\n lower === 'content-length' ||\n lower === 'transfer-encoding'\n )\n continue;\n forwardHeaders[key] = Array.isArray(value) ? value.join(',') : value;\n }\n\n // Inject identity headers so workspace-proxy auth passes.\n // Direct server-side calls bypass nginx (which normally injects X-Gen3-User-ID /\n // REMOTE_USER from the validated access_token), so we must add them explicitly.\n // SECURITY: decodeJwtClaims below does not verify the JWT signature — it relies on\n // Ambassador/revproxy having already done so before this code path is reached. When\n // serverExtensionProxyBaseUrl (WORKSPACE_PROXY_URL) targets workspace-proxy directly,\n // that verification is skipped entirely, so a caller could supply a correctly-shaped\n // but unsigned/forged JWT to impersonate another user via REMOTE_USER/X-Gen3-User-ID.\n // Only point serverExtensionProxyBaseUrl at a network path a user's own request cannot\n // otherwise forge, or add real signature verification (e.g. against Fence's JWKS)\n // here before trusting these claims.\n const jwt = getToken ? getToken(req) : extractTokenFallback(req);\n if (jwt) {\n const claims = decodeJwtClaims(jwt);\n const rawUsername =\n claims?.sub ?? claims?.preferred_username ?? claims?.username;\n if (typeof rawUsername === 'string') {\n const safeUsername = rawUsername.replace(/[\\r\\n]/g, '');\n const safeJwt = jwt.replace(/[\\r\\n]/g, '');\n forwardHeaders['Authorization'] = `Bearer ${safeJwt}`;\n forwardHeaders['REMOTE_USER'] = safeUsername;\n forwardHeaders['X-Gen3-User-ID'] = safeUsername;\n }\n }\n\n const method = (req.method || 'GET').toUpperCase();\n let body: Buffer | undefined;\n if (!['GET', 'HEAD'].includes(method)) {\n try {\n body = await readBody(req);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(\n `[workspace-assets] failed to read request body for ${method} ${targetUrl}: ${message}`,\n );\n res.status(500).end('Failed to read request body');\n return;\n }\n if (body?.length) {\n forwardHeaders['content-length'] = String(body.length);\n }\n }\n\n const startedAt = Date.now();\n console.warn(\n `[workspace-assets] proxying ${method} ${targetUrl}${body?.length ? ` (body: ${body.length} bytes)` : ''}`,\n );\n await new Promise<void>((resolve) => {\n const parsed = new URL(targetUrl);\n const transport = parsed.protocol === 'https:' ? https : http;\n const reqOptions: https.RequestOptions = {\n method,\n hostname: parsed.hostname,\n port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),\n path: parsed.pathname + parsed.search,\n headers: forwardHeaders,\n };\n\n const proxyReq = transport.request(reqOptions, (proxyRes) => {\n const statusCode = proxyRes.statusCode ?? 502;\n res.status(statusCode);\n const skip = new Set(['transfer-encoding', 'content-length']);\n for (const [key, value] of Object.entries(proxyRes.headers)) {\n if (!skip.has(key.toLowerCase()) && value !== undefined) {\n res.setHeader(key, value);\n }\n }\n const log = statusCode >= 400 ? console.error : console.warn;\n log(\n `[workspace-assets] ${method} ${targetUrl} -> ${statusCode} (${Date.now() - startedAt}ms)`,\n );\n proxyRes.pipe(res, { end: true });\n proxyRes.on('end', resolve);\n });\n\n proxyReq.on('error', (err: NodeJS.ErrnoException) => {\n console.error(\n `[workspace-assets] extension proxy failed for ${method} ${targetUrl} after ${Date.now() - startedAt}ms: ${err.code ?? 'UNKNOWN'} ${err.message}`,\n );\n if (!res.headersSent) {\n res.status(502).end('Extension proxy unreachable');\n }\n resolve();\n });\n\n proxyReq.on('timeout', () => {\n console.error(\n `[workspace-assets] extension proxy timed out for ${method} ${targetUrl} after ${Date.now() - startedAt}ms`,\n );\n proxyReq.destroy();\n });\n\n if (body?.length) {\n proxyReq.write(body);\n }\n proxyReq.end();\n });\n}\n\n// ---------- factory ----------\n\nexport function createWorkspaceAssetsHandler(\n options?: WorkspaceAssetsHandlerOptions,\n) {\n const gatewayBaseUrl =\n options?.gatewayBaseUrl ??\n process.env.JUPYTER_GATEWAY_BASE_URL ??\n '/api/workspace/gateway/';\n\n const assetRoot = options?.assetRoot ?? defaultAssetRoot();\n\n // Keep this in for logging purposes\n console.log('jupyterlite assets root:', assetRoot);\n\n const disabledExtensions = options?.additionalDisabledExtensions\n ? [...REMOTE_DISABLED_EXTENSIONS, ...options.additionalDisabledExtensions]\n : REMOTE_DISABLED_EXTENSIONS;\n\n const branding: BrandingConfig | undefined =\n options?.appName || options?.faviconUrl || options?.pageTitle\n ? {\n appName: options.appName,\n faviconUrl: options.faviconUrl,\n pageTitle: options.pageTitle,\n }\n : undefined;\n\n const serverExtensionProxyPath = options?.serverExtensionProxyPath;\n const serverExtensionProxyBaseUrl = options?.serverExtensionProxyBaseUrl;\n const getToken = options?.getToken;\n\n const remoteInjectionConfig: RemoteInjectionConfig = {\n gatewayBaseUrl,\n disabledExtensions,\n fullThemesUrl: options?.fullThemesUrl ?? DEFAULT_FULL_THEMES_URL,\n remoteKernelsPath: options?.remoteKernelsPath,\n branding,\n };\n\n // Build the allowed-file sets once at factory time (not per-request) to\n // avoid unbounded I/O on every incoming request (CWE-770).\n const walkDir = (dir: string, set: Set<string>): void => {\n try {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = nodePath.join(dir, entry.name);\n if (entry.isDirectory()) {\n walkDir(full, set);\n } else {\n set.add(full);\n }\n }\n } catch {\n // Tier directory doesn't exist yet — set remains empty and handler will 404.\n }\n };\n\n const allowedFilesByTier: Record<string, Set<string>> = {\n free: new Set<string>(),\n remote: new Set<string>(),\n };\n for (const tier of ALLOWED_TIERS) {\n walkDir(nodePath.resolve(assetRoot, tier), allowedFilesByTier[tier]);\n }\n\n return function handler(\n req: NextApiRequest,\n res: NextApiResponse,\n ): Promise<void> | void {\n const { tier, path: pathSegments } = req.query;\n\n if (typeof tier !== 'string' || !ALLOWED_TIERS.has(tier)) {\n res.status(404).end('Not found');\n return;\n }\n\n const segments: string[] = Array.isArray(pathSegments)\n ? pathSegments\n : pathSegments\n ? [pathSegments]\n : [];\n\n let tierRoot: string;\n if (tier === 'free') {\n tierRoot = nodePath.resolve(assetRoot, 'free');\n } else if (tier === 'remote') {\n tierRoot = nodePath.resolve(assetRoot, 'remote');\n } else {\n res.status(404).end('Not found');\n return;\n }\n\n const safeSegments: string[] = [];\n for (const seg of segments) {\n if (\n typeof seg !== 'string' ||\n !SAFE_SEGMENT_RE.test(seg) ||\n seg === '.' ||\n seg === '..'\n ) {\n res.status(403).end('Forbidden');\n return;\n }\n safeSegments.push(nodePath.basename(seg));\n }\n\n // Proxy server extension API calls (e.g. jupyterlmod /module/*, jupyter-server-proxy\n // /server-proxy/*) to the configured upstream rather than attempting a static file\n // lookup, which would always 404.\n if (\n tier === 'remote' &&\n serverExtensionProxyPath &&\n safeSegments.length > 0 &&\n SERVER_EXTENSION_PREFIXES.has(safeSegments[0])\n ) {\n const extensionPath = safeSegments.join('/');\n const rawQuery = req.url?.split('?')[1];\n const qs = rawQuery ? `?${rawQuery}` : '';\n const proxyBase =\n serverExtensionProxyBaseUrl ??\n (() => {\n const { proto, host } = resolveOrigin(req);\n return `${proto}://${host}`;\n })();\n const targetUrl = `${proxyBase}${serverExtensionProxyPath}/${extensionPath}${qs}`;\n return proxyServerExtension(req, res, targetUrl, getToken);\n }\n\n const allowedFiles = allowedFilesByTier[tier];\n\n const candidatePath = nodePath.resolve(tierRoot, ...safeSegments);\n const candidateIndex = nodePath.join(candidatePath, 'index.html');\n\n console.log('serving jupyterlite asset from', candidatePath);\n\n let filePath: string;\n if (allowedFiles.has(candidatePath)) {\n filePath = candidatePath;\n } else if (allowedFiles.has(candidateIndex)) {\n filePath = candidateIndex;\n } else {\n res.status(404).end('Not found');\n return;\n }\n\n const ext = nodePath.extname(filePath).toLowerCase();\n const contentType = MIME_TYPES[ext] || 'application/octet-stream';\n\n const isBuildAsset =\n filePath.includes(nodePath.join(tier, 'build')) ||\n filePath.includes(nodePath.join(tier, 'extensions'));\n\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');\n res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');\n res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');\n\n if (process.env.NODE_ENV === 'development') {\n // In dev there is no fence service to plant the access_token cookie, so\n // we derive it from credentials_token (which is NOT httpOnly in dev) and\n // set it here. The browser will then send it automatically with every\n // subsequent request to the same origin — including JupyterLite's direct\n // calls to /lw-workspace/proxy/jeg-proxy/api/kernelspecs (which bypass\n // the Next.js proxy and therefore need the cookie on the wire).\n const accessToken = req.cookies?.['credentials_token'];\n if (accessToken) {\n res.setHeader(\n 'Set-Cookie',\n `access_token=${encodeURIComponent(accessToken)}; Path=/; SameSite=Lax`,\n );\n }\n }\n\n if (nodePath.basename(filePath) === 'service-worker.js') {\n res.setHeader('Service-Worker-Allowed', '/');\n }\n\n const isRemoteLabHtml =\n tier === 'remote' &&\n ext === '.html' &&\n filePath.includes(nodePath.join('lab', 'index.html'));\n\n if (isRemoteLabHtml) {\n res.setHeader('Content-Type', contentType);\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n try {\n const html = fs.readFileSync(filePath, 'utf-8');\n const injected = injectRemoteConfig(html, req, remoteInjectionConfig);\n res.status(200).send(injected);\n } catch {\n res.status(500).end('Internal server error');\n }\n return;\n }\n\n // Non-remote HTML (e.g. free-tier lab) — apply branding if configured\n const isHtmlResponse = ext === '.html';\n if (isHtmlResponse && branding) {\n res.setHeader('Content-Type', contentType);\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n try {\n const html = fs.readFileSync(filePath, 'utf-8');\n res.status(200).send(injectBranding(html, branding));\n } catch {\n res.status(500).end('Internal server error');\n }\n return;\n }\n\n res.setHeader('Content-Type', contentType);\n res.setHeader(\n 'Cache-Control',\n isBuildAsset\n ? 'public, max-age=31536000, immutable'\n : 'public, max-age=3600, must-revalidate',\n );\n\n const stat = fs.statSync(filePath);\n if (stat.size > MAX_FILE_SIZE_BYTES) {\n res.status(413).end('File too large');\n return;\n }\n\n const stream = fs.createReadStream(filePath);\n stream.on('error', () => {\n res.status(500).end('Internal server error');\n });\n stream.pipe(res);\n };\n}\n\n/**\n * Default handler — for one-liner re-exports.\n *\n * Built lazily on the first request: `createWorkspaceAssetsHandler` walks both tier\n * asset trees at factory time, and this module is imported transitively by\n * `next.config.js` (via `@gen3/workspaces/server`), where that I/O is wasted.\n */\nlet lazyDefaultHandler:\n ReturnType<typeof createWorkspaceAssetsHandler> | undefined;\n\nconst defaultHandler = (\n req: NextApiRequest,\n res: NextApiResponse,\n): Promise<void> | void => {\n if (!lazyDefaultHandler) {\n lazyDefaultHandler = createWorkspaceAssetsHandler();\n }\n return lazyDefaultHandler(req, res);\n};\n\nexport default defaultHandler;\n","/**\n * Next.js config wrapper that adds all workspace-related plumbing.\n *\n * Usage (consumer's `next.config.js`):\n *\n * const { withJupyterWorkspaces } = require('@gen3/workspaces/server');\n * module.exports = withJupyterWorkspaces(yourNextConfig);\n */\n\nimport type { NextConfig } from 'next';\nimport nodePath from 'path';\nimport type { WebpackConfigContext } from 'next/dist/server/config-shared';\nimport type { Configuration } from 'webpack';\n\nexport interface WithJupyterWorkspacesOptions {\n /**\n * URL of the gateway proxy for local dev rewrites.\n * Default: env `GATEWAY_PROXY_URL` or `http://localhost:8890`\n */\n gatewayProxyUrl?: string;\n /**\n * Workspace page routes that need COOP/COEP headers.\n * Default: ['/workspaces/jupyter', '/workspaces/jupyter-lite', '/workspaces/jupyter-kernel']\n */\n workspaceRoutes?: string[];\n}\n\nconst DEFAULT_WORKSPACE_ROUTES = ['/Workspaces'];\n\nexport function withJupyterWorkspaces(\n nextConfig: NextConfig,\n options?: WithJupyterWorkspacesOptions,\n): NextConfig {\n const workspaceRoutes = options?.workspaceRoutes ?? DEFAULT_WORKSPACE_ROUTES;\n\n return {\n ...nextConfig,\n\n // Merge transpilePackages\n transpilePackages: [\n ...(nextConfig.transpilePackages ?? []),\n ...['@gen3/workspaces'].filter(\n (pkg) => !(nextConfig.transpilePackages ?? []).includes(pkg),\n ),\n ],\n\n // Merge webpack config — add React dedup alias\n webpack(config: Configuration, ctx: WebpackConfigContext) {\n config.resolve = config.resolve ?? {};\n config.resolve.alias = {\n ...config.resolve.alias,\n react: nodePath.dirname(require.resolve('react/package.json')),\n 'react-dom': nodePath.dirname(\n require.resolve('react-dom/package.json'),\n ),\n };\n\n // Chain the consumer's existing webpack config\n if (typeof nextConfig.webpack === 'function') {\n return nextConfig.webpack(config, ctx);\n }\n return config;\n },\n\n // Merge rewrites — add gateway proxy rewrite in dev mode\n async rewrites() {\n const isDev = process.env.NODE_ENV === 'development';\n\n const existing =\n typeof nextConfig.rewrites === 'function'\n ? await nextConfig.rewrites()\n : [];\n\n if (!isDev) return existing;\n\n const gatewayProxyUrl =\n options?.gatewayProxyUrl ??\n process.env.GATEWAY_PROXY_URL ??\n 'http://localhost:8890';\n\n const gatewayRewrite = {\n source: '/api/workspace/gateway/:path*',\n destination: `${gatewayProxyUrl}/api/workspace/gateway/:path*`,\n };\n\n // rewrites() can return an array or { beforeFiles, afterFiles, fallback }\n if (Array.isArray(existing)) {\n return [gatewayRewrite, ...existing];\n }\n return {\n ...existing,\n beforeFiles: [gatewayRewrite, ...(existing.beforeFiles ?? [])],\n };\n },\n\n // Merge headers — add COOP/COEP for workspace routes\n async headers() {\n const existing =\n typeof nextConfig.headers === 'function'\n ? await nextConfig.headers()\n : [];\n\n const coopCoepHeaders = workspaceRoutes.map((route) => ({\n source: route,\n headers: [\n { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },\n { key: 'Cross-Origin-Embedder-Policy', value: 'credentialless' },\n ],\n }));\n\n return [...existing, ...coopCoepHeaders];\n },\n };\n}\n","/**\n * createKernelLifecycleProxyHandler — server-side Next.js API route handler\n * for all kernel control-plane traffic.\n *\n * Security properties:\n * - Billing gate: POST /kernels fetches Fence /credentials/cdis first;\n * if that fails, no kernel is ever launched.\n * - Kernel spec filtering: the browser receives only the names/costs defined in policy.\n * - REMOTE_USER forwarded on every upstream request — JEG enforces per-user isolation.\n * - KERNEL_ID_RE validates all kernel IDs before they reach the upstream URL.\n *\n * Token extraction:\n * Pass getToken to reuse the host app's cookie logic (strongly recommended).\n * In gen3-vectis: `(req) => getAccessToken(req.headers['cookie'] ?? '') ?? null`\n * Ambassador performs RS256 verification before any request reaches Next.js.\n *\n * Usage (src/pages/api/workspace/kernel/[...action].ts — generated by bin/init.mjs):\n * import { createKernelLifecycleProxyHandler } from '@gen3/jupyter-workspaces/server';\n * import { getAccessToken } from '../../lib/auth/getLoginStatus';\n * const policy = process.env.KERNEL_SPEC_POLICY ? JSON.parse(process.env.KERNEL_SPEC_POLICY) : {};\n * export default createKernelLifecycleProxyHandler({\n * gen3Endpoint: process.env.GEN3_ENDPOINT,\n * fenceUrl: process.env.FENCE_URL,\n * kernelSpecPolicy: policy,\n * getToken: (req) => getAccessToken(req.headers['cookie'] ?? '') ?? null,\n * });\n * export const config = { api: { bodyParser: false } };\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { decodeJwtClaims, extractTokenFallback } from './utils';\nimport { fetchFence, GEN3_FENCE_SERVICE } from '@gen3/core';\nimport { GEN3_FENCE_API } from '@gen3/core/server';\nimport { JEG_SERVICE_API } from '../constants';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** Kernel spec filtering and cost annotation policy (server-side only). */\nexport interface KernelSpecPolicy {\n /**\n * Raw JEG kernel spec names that are permitted for this deployment.\n * Only these will be returned to the browser.\n */\n allowedSpecs: string[];\n /**\n * Cost per hour for each spec. 0 = included in base subscription.\n * Injected into the spec as `costPerHour` before returning to browser.\n */\n costPerHour: Record<string, number>;\n /**\n * Human-readable display name per spec (replaces raw JEG spec name).\n * e.g. { \"python3_gpu_a100\": \"Python (GPU A100 — $2.40/hr)\" }\n */\n displayNames: Record<string, string>;\n /**\n * Node type label for UI badge.\n * e.g. { \"python3_micro\": \"micro\", \"python3_gpu_a100\": \"gpu\" }\n */\n nodeType: Record<string, string>;\n}\n\nexport interface BillingEvent {\n username: string;\n action: 'launch' | 'terminate';\n kernelSpec?: string;\n kernelId?: string;\n costTier: number;\n timestamp: string;\n}\n\nexport interface KernelLifecycleProxyConfig {\n /**\n * External hostname for Ambassador routing, e.g. \"mycommons.example.com\"\n * or \"localhost:30080\" in local dev.\n * Used to build the upstream URL: https://{gen3Endpoint}/lw-workspace/proxy/...\n */\n gen3Endpoint: string | undefined;\n /** Internal URL of the Fence service, e.g. http://fence.fence.svc:80 */\n fenceUrl: string | undefined;\n /** Kernel spec filtering + billing policy (server-side only). */\n kernelSpecPolicy: Partial<KernelSpecPolicy>;\n /**\n * Set to true when JEG is configured and enabled for this deployment.\n * Controlled by ENABLE_JEG=true env var in gen3-vectis.\n * When false (default), all routes except GET /api/status return 503 silently so\n * the UI fails gracefully without error spam.\n */\n jegEnabled?: boolean;\n /**\n * Number of idle days before a kernel is considered stale (for /api/reap).\n * Defaults to 10. Controlled by JEG_IDLE_KILL_DAYS env var.\n */\n idleKillDays?: number;\n /**\n * Maximum kernel age in days regardless of idle state (for /api/reap).\n * Defaults to 15. Controlled by JEG_MAX_KERNEL_AGE_DAYS env var.\n */\n maxKernelAgeDays?: number;\n /**\n * Optional billing event sink. Defaults to structured JSON to stdout (CloudWatch).\n * Swap for DynamoDB, Stripe, etc. without changing any other code.\n * The function MUST NOT block — fire and forget.\n */\n billingSink?: (event: BillingEvent) => void;\n /**\n * Token extractor injected by the host application.\n * In gen3-vectis: `(req) => getAccessToken(req.headers['cookie'] ?? '') ?? null`\n * When omitted a minimal Bearer-header/cookie fallback is used (dev/standalone only).\n * Ambassador has already done RS256 verification — this is extraction only.\n */\n getToken?: (req: NextApiRequest) => string | null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Default billing sink — structured CloudWatch-compatible JSON log */\n/* ------------------------------------------------------------------ */\n\nfunction defaultBillingSink(event: BillingEvent): void {\n // CloudWatch Logs Insights picks up structured JSON automatically\n process.stdout.write(\n JSON.stringify({ type: 'WORKSPACE_BILLING', ...event }) + '\\n',\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Fence credential fetch */\n/* ------------------------------------------------------------------ */\n\ninterface FenceCreds {\n key_id: string;\n api_key: string; // pragma: allowlist secret\n}\n\nconst EMPTY_FENCE_CREDS: FenceCreds = {\n key_id: '',\n api_key: '', // pragma: allowlist secret\n};\n\nasync function fetchFenceCreds(\n fenceUrl: string,\n jwt: string,\n): Promise<FenceCreds> {\n let parsedFenceUrl: URL;\n try {\n parsedFenceUrl = new URL(fenceUrl);\n } catch {\n throw new Error('Fence URL is misconfigured.');\n }\n if (\n parsedFenceUrl.protocol !== 'http:' &&\n parsedFenceUrl.protocol !== 'https:'\n ) {\n throw new Error('Fence URL is misconfigured.');\n }\n try {\n const response = await fetchFence<FenceCreds>(\n {\n endpoint: 'credentials/api',\n method: 'GET',\n headers: {\n Authorization: `Bearer ${jwt}`,\n 'Content-Type': 'application/json',\n },\n },\n process.env.NODE_ENV === 'production', // use the FENCE Service if in production\n );\n if (!response?.data?.api_key) {\n console.error('No valid API key found in Fence response');\n return {\n api_key: '', // pragma: allowlist secret\n key_id: '',\n };\n }\n return response.data;\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error('Error fetching API key from Fence:', error);\n } else {\n console.error('Error fetching API key from Fence');\n }\n return EMPTY_FENCE_CREDS;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Kernel spec response transformation */\n/* ------------------------------------------------------------------ */\n\ninterface RawKernelSpecsResponse {\n default: string;\n kernelspecs: Record<\n string,\n {\n name: string;\n spec: {\n display_name: string;\n language: string;\n argv?: string[];\n metadata?: Record<string, unknown>;\n };\n resources?: Record<string, string>;\n }\n >;\n}\n\nfunction filterAndAnnotateSpecs(\n raw: RawKernelSpecsResponse,\n policy: Partial<KernelSpecPolicy>,\n): RawKernelSpecsResponse {\n const allowedSpecs = policy.allowedSpecs ?? [];\n const costPerHour = policy.costPerHour ?? {};\n const displayNames = policy.displayNames ?? {};\n const nodeType = policy.nodeType ?? {};\n\n if (allowedSpecs.length === 0) {\n // No policy configured — return everything unannotated (useful during dev bootstrap)\n return raw;\n }\n\n const filteredSpecs: RawKernelSpecsResponse['kernelspecs'] = {};\n\n for (const specName of allowedSpecs) {\n const rawSpec = raw.kernelspecs[specName];\n if (!rawSpec) continue; // JEG doesn't have this spec — skip silently\n\n filteredSpecs[specName] = {\n ...rawSpec,\n spec: {\n ...rawSpec.spec,\n // Override display_name with our curated name if provided\n display_name: displayNames[specName] ?? rawSpec.spec.display_name,\n // Inject billing metadata into spec.metadata (available to browser)\n metadata: {\n ...rawSpec.spec.metadata,\n costPerHour: costPerHour[specName] ?? 0,\n nodeType: nodeType[specName] ?? 'unknown',\n },\n },\n };\n }\n\n // Use first allowed spec as default if original default was filtered out\n const filteredDefault = allowedSpecs.includes(raw.default)\n ? raw.default\n : (allowedSpecs[0] ?? '');\n\n return { default: filteredDefault, kernelspecs: filteredSpecs };\n}\n\n/* ------------------------------------------------------------------ */\n/* Body buffering (Next.js bodyParser: false) */\n/* ------------------------------------------------------------------ */\n\nfunction readBody(req: NextApiRequest): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => chunks.push(chunk));\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Ambassador upstream URL builder */\n/* ------------------------------------------------------------------ */\n\n// function buildAmbassadorUrl(gen3Endpoint: string, kernelPath: string): string {\n// // gen3Endpoint may or may not have a scheme\n// const base = gen3Endpoint.startsWith('http')\n// ? gen3Endpoint\n// : `https://${gen3Endpoint}`;\n// const parsed = new URL(base);\n// if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n// throw new Error('gen3Endpoint must use http or https protocol.');\n// }\n// return `${parsed.origin}${parsed.pathname.replace(/\\/$/, '')}/lw-workspace/proxy${kernelPath}`;\n// }\n\nfunction buildAmbassadorUrl(gen3Endpoint: string, kernelPath: string): string {\n // gen3Endpoint may or may not have a scheme\n const base = gen3Endpoint.startsWith('http')\n ? gen3Endpoint\n : `https://${gen3Endpoint}`;\n const parsed = new URL(base);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error('gen3Endpoint must use http or https protocol.');\n }\n return `${parsed.origin}${parsed.pathname.replace(/\\/$/, '')}/lw-workspace/proxy${kernelPath}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Route matching */\n/* ------------------------------------------------------------------ */\n\nconst KERNEL_ID_RE = /^[a-f0-9-]{8,36}$/i;\n\ntype KernelRoute =\n | { type: 'kernelspecs' }\n | { type: 'kernels_list' }\n | { type: 'kernel_launch' }\n | { type: 'kernel_delete'; kernelId: string }\n | { type: 'kernel_passthrough'; kernelPath: string }\n | { type: 'status' }\n | { type: 'reap' };\n\ntype SimpleRoute = Exclude<\n KernelRoute,\n { type: 'kernel_delete' | 'kernel_passthrough' }\n>;\n\n// Table-driven simple routes: all match /api/{resource} with no kernel ID segment.\nconst SIMPLE_ROUTES = new Map<string, SimpleRoute>([\n ['GET:status', { type: 'status' }],\n ['POST:reap', { type: 'reap' }],\n ['GET:kernelspecs', { type: 'kernelspecs' }],\n ['GET:kernels', { type: 'kernels_list' }],\n ['POST:kernels', { type: 'kernel_launch' }],\n]);\n\nfunction resolveKernelRoute(\n method: string,\n actionSegments: string[],\n): KernelRoute | null {\n const [seg1, seg2] = actionSegments;\n\n if (!seg2) {\n return SIMPLE_ROUTES.get(`${method}:${seg1}`) ?? null;\n }\n\n // Routes with a kernel ID segment — validate format before use.\n if (seg1 === 'kernels' && KERNEL_ID_RE.test(seg2)) {\n if (method === 'DELETE') {\n return { type: 'kernel_delete', kernelId: seg2 };\n }\n // GET /api/kernels/{id}/channels or similar (passthrough for WebSocket upgrade info)\n if (method === 'GET') {\n const rest = actionSegments.slice(2).join('/');\n return {\n type: 'kernel_passthrough',\n kernelPath: `/api/kernels/${seg2}/${rest}`,\n };\n }\n }\n\n return null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Main factory — shared types and per-route handlers */\n/* ------------------------------------------------------------------ */\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\ninterface RouteContext {\n req: NextApiRequest;\n gen3Endpoint: string;\n fenceUrl: string | undefined;\n kernelSpecPolicy: Partial<KernelSpecPolicy>;\n ambassadorHeaders: Record<string, string>;\n /** Unsanitised JWT — use only for non-header contexts (e.g. Fence fetch body). */\n jwt: string;\n username: string;\n sink: (event: BillingEvent) => void;\n idleKillDays: number;\n maxKernelAgeDays: number;\n}\n\n/* -------- GET /api/kernelspecs -------- */\nasync function handleKernelSpecs(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernelspecs');\n try {\n const upRes = await fetch(upstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n if (!upRes.ok) {\n res\n .status(upRes.status)\n .json({ error: `Gateway ${upRes.status}: ${upRes.statusText}` });\n return;\n }\n const rawSpecs = (await upRes.json()) as RawKernelSpecsResponse;\n res\n .status(200)\n .json(filterAndAnnotateSpecs(rawSpecs, ctx.kernelSpecPolicy));\n } catch {\n res.status(502).json({ error: 'Failed to fetch kernel specs.' });\n }\n}\n\n/* -------- GET /api/kernels -------- */\nasync function handleKernelsList(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernels');\n try {\n const upRes = await fetch(upstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n if (!upRes.ok) {\n res\n .status(upRes.status)\n .json({ error: `Gateway ${upRes.status}: ${upRes.statusText}` });\n return;\n }\n res.status(200).json(await upRes.json());\n } catch {\n res.status(502).json({ error: 'Failed to list kernels.' });\n }\n}\n\n/* -------- POST /api/reap — bulk-delete stale/aged kernels -------- */\nasync function handleReap(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n // const listUpstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernels');\n const listUpstream = `${ctx.gen3Endpoint}/api/kernels`;\n let kernelList: Array<{ id: string; name: string; last_activity?: string }> =\n [];\n try {\n const listRes = await fetch(listUpstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n\n if (!listRes.ok) {\n res\n .status(listRes.status)\n .json({ error: `Failed to list kernels: ${listRes.status}` });\n return;\n }\n kernelList = (await listRes.json()) as typeof kernelList;\n } catch (err) {\n res.status(502).json({ error: `Kernel list unavailable: ${errMsg(err)}` });\n return;\n }\n\n const now = Date.now();\n const idleKillMins = ctx.idleKillDays * 24 * 60;\n const maxAgeMins = ctx.maxKernelAgeDays * 24 * 60;\n const reaped: string[] = [];\n const errors: string[] = [];\n\n for (const kernel of kernelList) {\n if (!KERNEL_ID_RE.test(kernel.id)) continue; // skip any malformed IDs from upstream\n const lastActivity = kernel.last_activity\n ? new Date(kernel.last_activity).getTime()\n : 0;\n const idleMins =\n lastActivity > 0 ? (now - lastActivity) / 60_000 : Infinity;\n if (idleMins <= idleKillMins && idleMins <= maxAgeMins) continue;\n\n const deleteUpstream = buildAmbassadorUrl(\n ctx.gen3Endpoint,\n `/api/kernels/${encodeURIComponent(kernel.id)}`,\n );\n try {\n await fetch(deleteUpstream, {\n method: 'DELETE',\n headers: ctx.ambassadorHeaders,\n });\n reaped.push(kernel.id);\n ctx.sink({\n username: ctx.username,\n action: 'terminate',\n kernelId: kernel.id,\n costTier: 0,\n timestamp: new Date().toISOString(),\n });\n } catch {\n errors.push(kernel.id);\n }\n }\n\n res.status(200).json({ reaped, errors });\n}\n\n/* -------- POST /api/kernels — launch with Fence cred injection -------- */\nasync function handleKernelLaunch(\n ctx: RouteContext,\n res: NextApiResponse,\n): Promise<void> {\n if (!ctx.fenceUrl) {\n res.status(503).json({ error: 'FENCE_URL is not configured.' });\n return;\n }\n\n // 1. Fetch per-user S3 credentials from Fence.\n // If this fails, we return 502 and do NOT launch a kernel.\n let fenceCreds: FenceCreds;\n try {\n fenceCreds = await fetchFenceCreds(ctx.fenceUrl, ctx.jwt);\n } catch (err) {\n res\n .status(502)\n .json({ error: `Storage credentials unavailable: ${errMsg(err)}` });\n return;\n }\n\n // 2. Read the original launch body from the client.\n const rawBody = await readBody(ctx.req);\n let launchBody: Record<string, unknown> = {};\n try {\n launchBody = JSON.parse(rawBody.toString('utf8')) as Record<\n string,\n unknown\n >;\n } catch {\n // empty or invalid JSON — proceed with empty body\n }\n\n const kernelSpec = (launchBody.name as string) || '';\n\n // 3. Inject gen3-fuse credential env vars into the kernel launch body.\n // JEG forwards these to the kernel pod → init container writes /.gen3/credentials.json\n // → gen3-fuse sidecar mounts the user's S3 bucket.\n const enrichedBody = {\n ...launchBody,\n env: {\n ...(launchBody.env as Record<string, string>),\n GEN3_API_KEY_ID: fenceCreds.key_id,\n GEN3_API_KEY_SECRET: fenceCreds.api_key, // pragma: allowlist secret\n NAMESPACE: process.env.NAMESPACE || 'jupyter-pods',\n GEN3_ENDPOINT: ctx.gen3Endpoint,\n },\n };\n\n // 4. Non-blocking billing event (launch intent).\n const launchTimestamp = new Date().toISOString();\n const costTier = ctx.kernelSpecPolicy.costPerHour?.[kernelSpec] ?? 0;\n ctx.sink({\n username: ctx.username,\n action: 'launch',\n kernelSpec,\n costTier,\n timestamp: launchTimestamp,\n });\n\n // TODO:\n // BILLING_HOOK: pricing/quota check — runs before kernel is launched.\n // Replace the resolved value below with an async pricing/quota API call.\n // Return false here to block launch with a 402 Payment Required.\n // Example: const approved = await checkQuotaAndPrice({ username, kernelSpec, costTier });\n const billingApproved = true; // TODO: hook pricing gate here\n if (!billingApproved) {\n res\n .status(402)\n .json({ error: 'Kernel launch requires billing authorization.' });\n return;\n }\n\n // 5. Forward to JEG via Ambassador.\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, '/api/kernels');\n let launchRes: Response;\n try {\n launchRes = await fetch(upstream, {\n method: 'POST',\n headers: { ...ctx.ambassadorHeaders, 'Content-Type': 'application/json' },\n body: JSON.stringify(enrichedBody),\n });\n } catch (err) {\n res.status(502).json({ error: `Kernel launch failed: ${errMsg(err)}` });\n return;\n }\n\n if (!launchRes.ok) {\n res.status(launchRes.status).json({\n error: `Kernel launch failed: ${launchRes.status} ${launchRes.statusText}`,\n });\n return;\n }\n\n const kernelData = (await launchRes.json()) as Record<string, unknown>;\n\n // 6. Non-blocking: record kernelId in billing log.\n const kernelId = kernelData?.id as string | undefined;\n if (kernelId) {\n ctx.sink({\n username: ctx.username,\n action: 'launch',\n kernelSpec,\n kernelId,\n costTier,\n timestamp: launchTimestamp,\n });\n }\n\n res.status(201).json(kernelData);\n}\n\n/* -------- DELETE /api/kernels/{id} -------- */\nasync function handleKernelDelete(\n ctx: RouteContext,\n route: Extract<KernelRoute, { type: 'kernel_delete' }>,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(\n ctx.gen3Endpoint,\n `/api/kernels/${encodeURIComponent(route.kernelId)}`,\n );\n try {\n const upRes = await fetch(upstream, {\n method: 'DELETE',\n headers: ctx.ambassadorHeaders,\n });\n // 404 = already gone = success (idempotent terminate)\n if (!upRes.ok && upRes.status !== 404) {\n res.status(upRes.status).json({\n error: `Kernel terminate failed: ${upRes.status} ${upRes.statusText}`,\n });\n return;\n }\n } catch (err) {\n res.status(502).json({ error: `Kernel terminate failed: ${errMsg(err)}` });\n return;\n }\n\n // Non-blocking billing event (terminate)\n ctx.sink({\n username: ctx.username,\n action: 'terminate',\n kernelId: route.kernelId,\n costTier: 0, // actual cost determined from launch event by billing system\n timestamp: new Date().toISOString(),\n });\n\n res.status(204).end();\n}\n\n/* -------- GET /api/kernels/{id}/... passthrough -------- */\nasync function handleKernelPassthrough(\n ctx: RouteContext,\n route: Extract<KernelRoute, { type: 'kernel_passthrough' }>,\n res: NextApiResponse,\n): Promise<void> {\n const upstream = buildAmbassadorUrl(ctx.gen3Endpoint, route.kernelPath);\n try {\n const upRes = await fetch(upstream, {\n method: 'GET',\n headers: ctx.ambassadorHeaders,\n });\n res.status(upRes.status).json(await upRes.json().catch(() => ({})));\n } catch {\n res.status(502).json({ error: 'Upstream unreachable.' });\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Factory */\n/* ------------------------------------------------------------------ */\n\nconst ALLOWED_FENCE_URLS = [GEN3_FENCE_SERVICE, GEN3_FENCE_API];\n\nconst ALLOWED_JEG_URLS = [JEG_SERVICE_API, '/lw-workspace/proxy/jeg-panel'];\n\nexport function createKernelProxyHandler(config: KernelLifecycleProxyConfig) {\n const sink = config.billingSink ?? defaultBillingSink;\n const jegEnabled = config.jegEnabled === true;\n const idleKillDays = config.idleKillDays ?? 10;\n const maxKernelAgeDays = config.maxKernelAgeDays ?? 15;\n\n return async function kernelLifecycleProxyHandler(\n req: NextApiRequest,\n res: NextApiResponse,\n ): Promise<void> {\n const { gen3Endpoint, fenceUrl, kernelSpecPolicy } = config;\n\n if (fenceUrl && !ALLOWED_FENCE_URLS.includes(fenceUrl)) {\n res.status(503).json({ error: 'Fence service URL is misconfigured.' });\n return;\n }\n\n if (gen3Endpoint && !ALLOWED_JEG_URLS.includes(gen3Endpoint)) {\n res.status(503).json({ error: 'JEG service URL is misconfigured.' });\n return;\n }\n\n // --- Route resolution (done early so /api/status can short-circuit) ---\n const rawAction = req.query.action;\n const actionSegments: string[] = Array.isArray(rawAction)\n ? rawAction.filter((s): s is string => typeof s === 'string')\n : [];\n const route = resolveKernelRoute(req.method || '', actionSegments);\n\n // GET /api/status is the JEG feature-gate probe — always returns 200 with { enabled }.\n // This allows useGatewayConnection to detect whether JEG is configured before polling.\n if (route?.type === 'status') {\n res.setHeader('Cache-Control', 'no-store');\n res.status(200).json({ enabled: jegEnabled });\n return;\n }\n\n // All other routes are gated — silently return 503 so the UI fails gracefully.\n if (!jegEnabled) {\n res.setHeader('Cache-Control', 'no-store');\n res\n .status(503)\n .json({ error: 'JEG not configured for this deployment.' });\n return;\n }\n\n if (!gen3Endpoint) {\n res.status(503).json({ error: 'GEN3_ENDPOINT is not configured.' });\n return;\n }\n\n // --- Auth: host-injected extractor first, minimal fallback for dev/standalone ---\n const jwt = config.getToken\n ? config.getToken(req)\n : extractTokenFallback(req);\n\n if (!jwt) {\n res.status(401).json({ error: 'Authentication required.' });\n return;\n }\n\n if (!route) {\n res.status(404).json({ error: 'Route not found.' });\n return;\n }\n\n // Extract sub claim for REMOTE_USER — Ambassador already verified the signature.\n const claims = decodeJwtClaims(jwt);\n const rawUsername =\n claims?.sub ??\n claims?.preferred_username ??\n claims?.username ??\n 'unknown';\n const username: string =\n typeof rawUsername === 'string' ? rawUsername : 'unknown';\n\n // Strip CRLF to prevent HTTP header injection (defense-in-depth)\n const safeJwt = jwt.replace(/[\\r\\n]/g, '');\n const safeUsername = username.replace(/[\\r\\n]/g, '');\n\n const ambassadorHeaders: Record<string, string> = {\n Authorization: `Bearer ${safeJwt}`,\n REMOTE_USER: safeUsername,\n };\n\n // No-store for all control plane responses\n res.setHeader('Cache-Control', 'no-store');\n\n const ctx: RouteContext = {\n req,\n gen3Endpoint,\n fenceUrl,\n kernelSpecPolicy,\n ambassadorHeaders,\n jwt,\n username,\n sink,\n idleKillDays,\n maxKernelAgeDays,\n };\n\n switch (route.type) {\n case 'kernelspecs':\n return handleKernelSpecs(ctx, res);\n case 'kernels_list':\n return handleKernelsList(ctx, res);\n case 'reap':\n return handleReap(ctx, res);\n case 'kernel_launch':\n return handleKernelLaunch(ctx, res);\n case 'kernel_delete':\n return handleKernelDelete(ctx, route, res);\n case 'kernel_passthrough':\n return handleKernelPassthrough(ctx, route, res);\n default:\n res.status(404).json({ error: 'Route not matched.' });\n }\n };\n}\n","/**\n * Next.js API route for JupyterLite static assets.\n *\n * The handler options are read from a per-commons JSON file:\n *\n * <GEN3_FRONTEND_CONFIGURATION_ROOT>/<GEN3_COMMONS_NAME>/workspaceAssets.json\n *\n * matching the convention used by the rest of the framework's server-side\n * configuration (see `FilesystemContent` / `GEN3_FRONTEND_CONFIGURATION_ROOT`).\n * The file is optional — DEFAULT_OPTIONS below is used when it is absent or\n * unreadable, so a bad config never takes down the whole assets route.\n *\n * The upstream handler is built lazily on first request rather than at import\n * time: `createWorkspaceAssetsHandler` recursively walks both tier asset trees\n * when constructed, and this module is imported transitively by\n * `next.config.js` (via `@gen3/workspaces/server`) where that I/O is wasted.\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport fs from 'fs';\nimport nodePath from 'path';\nimport { GEN3_COMMONS_NAME } from '@gen3/core';\nimport { getAccessToken } from '@gen3/frontend/server';\nimport {\n createWorkspaceAssetsHandler,\n type WorkspaceAssetsHandlerOptions,\n} from '../server/workspaceAssetsHandler';\n\nconst CONFIG_ROOT = process.env.GEN3_FRONTEND_CONFIGURATION_ROOT || './config/';\nconst CONFIG_FILENAME = 'workspaceAssets.json';\n\nconst DEFAULT_OPTIONS: WorkspaceAssetsHandlerOptions = {\n // Route JupyterLite remote-mode kernel WebSocket traffic through revproxy's\n // /lw-workspace/proxy/ nginx block → ambassador-service (ExternalName → Emissary)\n // → JEG. Next.js API routes cannot handle WebSocket upgrades, so we must\n // bypass them and use the nginx path that has allow_upgrade + long timeouts.\n gatewayBaseUrl: '/lw-workspace/proxy/',\n // Route all kernel ops through jeg-proxy so JupyterLite sees merged Python3\n // (container) + JEG GPU kernelspecs. The proxy routes Python3 kernel\n // launches/channels to the container; GPU kernel launches are gated (403)\n // with a message to use the Kernel Panel.\n remoteKernelsPath: '/lw-workspace/proxy/jeg-proxy',\n // Proxy server extension REST calls (jupyterlmod /module/*, jupyter-server-proxy\n // /server-proxy/*) to jeg-proxy. These calls originate from JupyterLab extensions\n // in the remote build and resolve relative to the JupyterLite base URL, which points\n // at this static-file handler — without a proxy they always 404.\n serverExtensionProxyPath: '/lw-workspace/proxy',\n // Optional internal k8s service base URL for the extension proxy. When set,\n // proxy requests target this address directly instead of routing through the\n // ingress (avoiding self-signed-cert issues). Readable from the JSON config\n // file or the WORKSPACE_PROXY_URL env var.\n serverExtensionProxyBaseUrl: process.env.WORKSPACE_PROXY_URL || undefined,\n // Direct calls to serverExtensionProxyBaseUrl bypass nginx, which normally\n // injects the X-Gen3-User-ID/REMOTE_USER headers workspace-proxy requires —\n // reuse this app's cookie extraction to inject them explicitly instead.\n getToken: (req) => getAccessToken(req.headers['cookie'] ?? '') ?? null,\n // in-browser Pyodide kernel must not be offered alongside it.\n additionalDisabledExtensions: [\n '@jupyterlite/pyodide-kernel-extension:kernel',\n ],\n appName: GEN3_COMMONS_NAME,\n};\n\nconst STRING_OPTIONS = [\n 'gatewayBaseUrl',\n 'assetRoot',\n 'appName',\n 'faviconUrl',\n 'pageTitle',\n 'remoteKernelsPath',\n 'fullThemesUrl',\n 'serverExtensionProxyPath',\n 'serverExtensionProxyBaseUrl',\n] as const satisfies ReadonlyArray<keyof WorkspaceAssetsHandlerOptions>;\n\nfunction configFilePath(): string {\n return nodePath.resolve(\n process.cwd(),\n CONFIG_ROOT,\n GEN3_COMMONS_NAME,\n CONFIG_FILENAME,\n );\n}\n\n/**\n * Pick and type-check the known option keys. Unknown keys are ignored so a\n * config file can carry extra metadata without reaching the factory,\n * and a wrong-typed value falls back to its default instead of throwing.\n */\nfunction parseOptions(raw: unknown): WorkspaceAssetsHandlerOptions {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n console.warn(\n `[workspace-assets] ${CONFIG_FILENAME} is not a JSON object; using defaults.`,\n );\n return DEFAULT_OPTIONS;\n }\n\n const source = raw as Record<string, unknown>;\n const parsed: WorkspaceAssetsHandlerOptions = {};\n\n for (const key of STRING_OPTIONS) {\n const value = source[key];\n if (value === undefined) continue;\n if (typeof value === 'string') {\n parsed[key] = value;\n } else {\n console.warn(\n `[workspace-assets] ignoring ${key}: expected a string, got ${typeof value}.`,\n );\n }\n }\n\n const extensions = source.additionalDisabledExtensions;\n\n // oxlint-disable-next-line no-console\n console.log(\n 'additional disabled extensions',\n source.additionalDisabledExtensions,\n );\n if (extensions !== undefined) {\n if (\n Array.isArray(extensions) &&\n extensions.every((entry) => typeof entry === 'string')\n ) {\n parsed.additionalDisabledExtensions = extensions;\n } else {\n console.warn(\n '[workspace-assets] ignoring additionalDisabledExtensions: expected an array of strings.',\n );\n }\n }\n\n // oxlint-disable-next-line no-console\n console.log('parsed options', parsed);\n\n return { ...DEFAULT_OPTIONS, ...parsed };\n}\n\nfunction loadOptions(): WorkspaceAssetsHandlerOptions {\n const file = configFilePath();\n try {\n return parseOptions(JSON.parse(fs.readFileSync(file, 'utf-8')));\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n console.warn(\n `[workspace-assets] could not read ${file} (${reason}); using defaults.`,\n );\n return DEFAULT_OPTIONS;\n }\n}\n\nlet upstreamHandler:\n ReturnType<typeof createWorkspaceAssetsHandler> | undefined;\nlet loadedConfigMtimeMs: number | undefined;\n\n/** mtime of the config file, or undefined when it does not exist. */\nfunction configMtimeMs(): number | undefined {\n try {\n return fs.statSync(configFilePath()).mtimeMs;\n } catch {\n return undefined;\n }\n}\n\nfunction getUpstreamHandler(): ReturnType<typeof createWorkspaceAssetsHandler> {\n if (process.env.NODE_ENV === 'development') {\n // Rebuild when the config file changes so edits don't need a dev-server\n // restart. Only the cheap stat runs per request — the expensive asset walk\n // happens on the first request and then only after a real config change.\n const mtimeMs = configMtimeMs();\n if (upstreamHandler && mtimeMs !== loadedConfigMtimeMs) {\n upstreamHandler = undefined;\n }\n loadedConfigMtimeMs = mtimeMs;\n }\n\n if (!upstreamHandler) {\n upstreamHandler = createWorkspaceAssetsHandler(loadOptions());\n }\n return upstreamHandler;\n}\n\nexport default function handler(req: NextApiRequest, res: NextApiResponse) {\n return getUpstreamHandler()(req, res);\n}\n","import type { NextApiRequest, NextApiResponse } from 'next';\nimport { getCookie } from 'cookies-next';\n\n// Allowed path prefixes — keeps proxying scoped to the Jupyter Gateway API surface\nconst ALLOWED_PREFIXES = ['/api/kernels', '/api/sessions', '/api/kernelspecs'];\n\nfunction buildUpstreamPath(segments: string[]): string {\n const clean = segments\n .filter(Boolean)\n .map((s) => s.replace(/^\\/+|\\/+$/g, ''));\n\n if (clean.some((s) => s === '..' || s === '.')) {\n throw new Error('Invalid path segment');\n }\n\n return `/${clean.join('/')}`;\n}\n\nfunction isAllowedPath(path: string): boolean {\n return ALLOWED_PREFIXES.some(\n (prefix) => path === prefix || path.startsWith(`${prefix}/`),\n );\n}\n\nfunction buildQueryString(\n rawUrl: string | undefined,\n excludeKey: string,\n): string {\n if (!rawUrl) return '';\n const queryPart = rawUrl.split('?')[1];\n if (!queryPart) return '';\n\n const params = new URLSearchParams(queryPart);\n params.delete(excludeKey);\n\n const result = params.toString();\n return result ? `?${result}` : '';\n}\n\nfunction readBody(req: NextApiRequest): Promise<Buffer | undefined> {\n return new Promise((resolve, reject) => {\n if (!req.method || ['GET', 'HEAD'].includes(req.method.toUpperCase())) {\n resolve(undefined);\n return;\n }\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer | string) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n req.on('end', () =>\n resolve(chunks.length ? Buffer.concat(chunks) : undefined),\n );\n req.on('error', reject);\n });\n}\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse,\n) {\n const gatewayUrl = process.env.JUPYTER_GATEWAY_URL;\n\n if (!gatewayUrl) {\n res.status(500).json({ error: 'JUPYTER_GATEWAY_URL is not configured' });\n return;\n }\n\n const gatewayBase = gatewayUrl.replace(/\\/+$/, '');\n\n const actionSegments = Array.isArray(req.query.action)\n ? req.query.action\n : req.query.action\n ? [req.query.action]\n : [];\n\n let upstreamPath: string;\n try {\n upstreamPath = buildUpstreamPath(actionSegments);\n } catch {\n res.status(400).json({ error: 'Invalid path' });\n return;\n }\n\n if (!isAllowedPath(upstreamPath)) {\n res.status(403).json({ error: 'Forbidden path' });\n return;\n }\n\n const queryString = buildQueryString(req.url, 'action');\n const targetUrl = `${gatewayBase}${upstreamPath}${queryString}`;\n\n const forwardHeaders = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (!value) continue;\n const lower = key.toLowerCase();\n if (\n lower === 'host' ||\n lower === 'content-length' ||\n lower === 'transfer-encoding'\n )\n continue;\n forwardHeaders.set(key, Array.isArray(value) ? value.join(',') : value);\n }\n\n // Inject server-side JEG token — overrides any client-supplied auth header.\n // This ensures calls from JupyterLite's own serverconnection.js are also authenticated.\n if (process.env.NODE_ENV === 'development') {\n // NOTE: This cookie can only be accessed from the client side\n // in development mode. Otherwise, the cookie is set as httpOnly\n const accessToken = getCookie('credentials_token');\n if (accessToken) {\n forwardHeaders.set('Authorization', `Bearer ${accessToken}`);\n }\n }\n\n let body: Buffer | undefined;\n try {\n body = await readBody(req);\n } catch {\n res.status(500).json({ error: 'Failed to read request body' });\n return;\n }\n\n if (body) {\n forwardHeaders.set('content-length', String(body.byteLength));\n }\n\n let upstream: Response;\n try {\n upstream = await fetch(targetUrl, {\n method: req.method,\n headers: forwardHeaders,\n body: body ? new Uint8Array(body) : undefined,\n signal: AbortSignal.timeout(30_000),\n });\n } catch (err) {\n const isTimeout = err instanceof Error && err.name === 'TimeoutError';\n res.status(isTimeout ? 504 : 502).json({\n error: isTimeout ? 'Gateway timeout' : 'Gateway unreachable',\n });\n return;\n }\n\n res.status(upstream.status);\n upstream.headers.forEach((value, key) => {\n const lower = key.toLowerCase();\n if (\n lower === 'transfer-encoding' ||\n lower === 'content-type' ||\n lower === 'content-security-policy'\n )\n return;\n res.setHeader(key, value);\n });\n\n const upstreamContentType = upstream.headers.get('content-type') || '';\n const safeContentType = /html|xml|svg/i.test(upstreamContentType)\n ? 'text/plain; charset=utf-8'\n : upstreamContentType || 'application/octet-stream';\n res.setHeader('Content-Type', safeContentType);\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('Content-Security-Policy', \"default-src 'none'; sandbox\");\n res.setHeader('Content-Disposition', 'attachment');\n\n if (upstream.body) {\n const reader = upstream.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } finally {\n reader.releaseLock();\n }\n res.end();\n } else {\n res.end();\n }\n}\n\nexport const config = { api: { bodyParser: false } };\n","// Kernel lifecycle proxy — billing gate + Fence credential injection.\n// Browser never sees JEG URL or raw kernel spec names.\n// POST /kernels calls Fence /credentials/cdis first — if it fails, no kernel is launched.\n// getToken reuses this app's cookie extraction — no JWT reinvention.\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { createKernelProxyHandler } from '../server/kernelLifecycleProxy';\nimport { getAccessToken } from '@gen3/frontend/server';\nimport { GEN3_FENCE_API } from '@gen3/core/server';\nimport { JEG_SERVICE_API } from '../constants';\nimport { GEN3_FENCE_SERVICE } from '@gen3/core';\n\nconst inCluster = Boolean(process.env.KUBERNETES_SERVICE_HOST);\nconst defaultGen3Endpoint = inCluster\n ? JEG_SERVICE_API\n : '/lw-workspace/proxy/jeg-panel';\nconst defaultFenceUrl = inCluster ? GEN3_FENCE_SERVICE : GEN3_FENCE_API;\n\nconst gen3Endpoint = process.env.JEG_SERVICE_API ?? defaultGen3Endpoint;\nconst fenceUrl = defaultFenceUrl;\n\nif (!gen3Endpoint) {\n console.warn(\n '[workspace-kernel] JEG_SERVICE_API is not set and not running in-cluster — kernel proxy will likely fail',\n );\n}\nif (!fenceUrl) {\n console.warn(\n '[workspace-kernel] FENCE_URL is not set and not running in-cluster — credential injection will likely fail',\n );\n}\n\nlet policy: Record<string, unknown> = {};\nif (process.env.KERNEL_SPEC_POLICY) {\n try {\n policy = JSON.parse(process.env.KERNEL_SPEC_POLICY);\n } catch (err) {\n throw new Error(\n `[workspace-kernel] KERNEL_SPEC_POLICY is not valid JSON: ${(err as Error).message}`,\n );\n }\n}\n\nconst upstreamHandler = createKernelProxyHandler({\n gen3Endpoint,\n fenceUrl,\n kernelSpecPolicy: policy,\n jegEnabled: process.env.ENABLE_JEG === 'true',\n getToken: (req) => {\n const token = getAccessToken(req.headers['cookie'] ?? '') ?? null;\n if (!token) {\n console.warn(\n '[workspace-kernel] No access token found in request cookies',\n );\n }\n return token;\n },\n});\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse,\n) {\n try {\n await upstreamHandler(req, res);\n } catch (err) {\n console.error('[workspace-kernel] Upstream handler threw:', err);\n if (!res.headersSent) {\n res.status(502).json({ error: 'Bad gateway' });\n }\n return;\n }\n}\n\nexport const config = { api: { bodyParser: false } };\n","/**\n * createHatcheryProxyHandler — server-side Next.js API route handler for Hatchery\n * micro-container lifecycle (launch, terminate, status, options).\n *\n * Security properties:\n * - Strict allowlist: only /options, /status, /launch, /terminate are proxied.\n * - All other paths return 404 — Hatchery internals are never reachable.\n * - JWT forwarded as Bearer; user identity set as REMOTE_USER for server-side isolation.\n * - `id` query param sanitized against SAFE_ID_RE (SSRF and injection prevention).\n *\n * Token extraction:\n * Pass getToken to reuse the host app's existing cookie logic (strongly recommended).\n * In gen3-vectis this is getAccessToken from lib/auth/getLoginStatus.\n * Without getToken, a minimal Bearer/cookie fallback is used (dev/standalone only).\n * Ambassador performs RS256 verification before any request reaches Next.js.\n *\n * Usage (src/pages/api/workspace/hatchery/[...action].ts — generated by bin/init.mjs):\n * import { createHatcheryProxyHandler } from '@gen3/jupyter-workspaces/server';\n * import { getAccessToken } from '../../lib/auth/getLoginStatus';\n * export default createHatcheryProxyHandler({\n * hatcheryUrl: process.env.HATCHERY_URL,\n * getToken: (req) => getAccessToken(req.headers['cookie'] ?? '') ?? null,\n * });\n * export const config = { api: { bodyParser: false } };\n */\n\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport {\n createProxyRequest,\n decodeJwtClaims,\n extractTokenFallback,\n} from './utils';\n\nexport interface HatcheryProxyConfig {\n /** Internal URL of the Hatchery service, e.g. http://hatchery.hatchery.svc:8000 */\n hatcheryUrl: string | undefined;\n /**\n * Token extractor injected by the host application.\n * In gen3-vectis: `(req) => getAccessToken(req.headers['cookie'] ?? '') ?? null`\n * When omitted, a minimal Bearer-header/cookie fallback is used (dev/standalone only).\n * Ambassador has already done RS256 verification — this is extraction only.\n */\n getToken?: (req: NextApiRequest) => string | null;\n}\n\ntype HatcheryRoute =\n | { method: 'GET'; path: '/options' }\n | { method: 'GET'; path: '/status' }\n | { method: 'POST'; path: '/launch' }\n | { method: 'POST'; path: '/terminate' };\n\nconst SAFE_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;\n\nfunction resolveHatcheryRoute(\n method: string,\n actionSegments: string[],\n): HatcheryRoute | null {\n const action = actionSegments[0] || '';\n const routes: Record<string, HatcheryRoute> = {\n 'GET:options': { method: 'GET', path: '/options' },\n 'GET:status': { method: 'GET', path: '/status' },\n 'POST:launch': { method: 'POST', path: '/launch' },\n 'POST:terminate': { method: 'POST', path: '/terminate' },\n };\n return routes[`${method}:${action}`] ?? null;\n}\n\nconst ALLOWED_HATCHERY_URLS = [\n '/lw-workspace',\n 'http://hatchery-service.gen3.svc.cluster.local',\n];\n\nexport function createHatcheryProxyHandler(config: HatcheryProxyConfig) {\n return async function hatcheryProxyHandler(\n req: NextApiRequest,\n res: NextApiResponse,\n ): Promise<void> {\n const hatcheryUrl = config.hatcheryUrl;\n\n if (!hatcheryUrl) {\n res.status(503).json({\n error: 'Hatchery service is not configured (HATCHERY_URL missing).',\n });\n return;\n }\n\n if (!ALLOWED_HATCHERY_URLS.includes(hatcheryUrl)) {\n res.status(503).json({ error: 'Hatchery service URL is misconfigured.' });\n return;\n }\n\n let parsedHatcheryUrl: URL;\n try {\n parsedHatcheryUrl = new URL(hatcheryUrl);\n } catch {\n res.status(503).json({ error: 'Hatchery service URL is misconfigured.' });\n return;\n }\n if (\n parsedHatcheryUrl.protocol !== 'http:' &&\n parsedHatcheryUrl.protocol !== 'https:'\n ) {\n res.status(503).json({ error: 'Hatchery service URL is misconfigured.' });\n return;\n }\n\n // --- Auth: host-injected extractor first, minimal fallback for dev/standalone ---\n const jwt = config.getToken\n ? config.getToken(req)\n : extractTokenFallback(req);\n if (!jwt) {\n res.status(401).json({ error: 'Authentication required.' });\n return;\n }\n\n // Validate JWT format to prevent injection attacks\n // JWT should be three base64url-encoded segments separated by dots\n const JWT_FORMAT_RE = /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\n if (!JWT_FORMAT_RE.test(jwt)) {\n console.error('[hatcheryProxy] Invalid JWT format detected');\n res.status(401).json({ error: 'Invalid authentication token format.' });\n return;\n }\n\n // Additional length check to prevent extremely long tokens\n if (jwt.length > 8192) {\n console.error('[hatcheryProxy] JWT exceeds maximum length');\n res.status(401).json({ error: 'Authentication token too long.' });\n return;\n }\n\n // Extract sub claim for REMOTE_USER — Ambassador already verified the signature.\n const claims = decodeJwtClaims(jwt);\n const rawUsername =\n claims?.sub ?? claims?.preferred_username ?? claims?.username;\n const username: string | undefined =\n typeof rawUsername === 'string' ? rawUsername : undefined;\n if (!username) {\n res\n .status(401)\n .json({ error: 'Unable to determine username from token.' });\n return;\n }\n // Strip CRLF to prevent HTTP header injection (defense-in-depth)\n const safeJwt = jwt.replace(/[\\r\\n]/g, '');\n const safeUsername = username.replace(/[\\r\\n]/g, '');\n\n // --- Route resolution ---\n const actionSegments = (req.query.action as string[]) || [];\n const route = resolveHatcheryRoute(req.method || '', actionSegments);\n if (!route) {\n res.status(404).json({ error: 'Route not found.' });\n return;\n }\n\n // --- Sanitize launch/terminate id param (SSRF prevention) ---\n let queryString = '';\n if (route.path === '/launch' || route.path === '/terminate') {\n const id = (req.query.id as string) || '';\n if (id) {\n if (!SAFE_ID_RE.test(id)) {\n res.status(400).json({ error: 'Invalid container identifier.' });\n return;\n }\n queryString = `?id=${encodeURIComponent(id)}`;\n }\n } else if (route.path === '/status' || route.path === '/options') {\n // Pass id through safely for status/options\n const id = (req.query.id as string) || '';\n if (id) {\n if (!SAFE_ID_RE.test(id)) {\n res.status(400).json({ error: 'Invalid container identifier.' });\n return;\n }\n queryString = `?id=${encodeURIComponent(id)}`;\n }\n }\n\n const hatcheryBase = `${parsedHatcheryUrl.origin}${parsedHatcheryUrl.pathname.replace(/\\/$/, '')}`;\n const targetUrl = `${hatcheryBase}${route.path}${queryString}`;\n\n await createProxyRequest({\n req,\n res,\n targetUrl,\n method: route.method,\n extraHeaders: {\n Authorization: `Bearer ${safeJwt}`,\n REMOTE_USER: safeUsername,\n remote_user: safeUsername,\n },\n // Hatchery doesn't need a body for GET routes\n forwardBody: route.method === 'POST',\n });\n };\n}\n","// Hatchery proxy — strict allowlist: /options, /status, /launch, /terminate\n// Injects Authorization + REMOTE_USER headers; sanitizes id param (SSRF prevention).\n// getToken reuses this app's cookie extraction — no JWT reinvention.\nimport { createHatcheryProxyHandler } from '../server/hatcheryProxy';\nimport { getAccessToken } from '@gen3/frontend/server';\nimport type { NextApiRequest, NextApiResponse } from 'next';\n\nconst defaultHatcheryUrl = process.env.KUBERNETES_SERVICE_HOST\n ? 'http://hatchery-service.gen3.svc.cluster.local'\n : '/lw-workspace';\n\nconst upstreamHandler = createHatcheryProxyHandler({\n hatcheryUrl: defaultHatcheryUrl,\n getToken: (req) => getAccessToken(req.headers['cookie'] ?? '') ?? null,\n});\n\n// oxlint-disable-next-line no-unused-vars\nfunction decodeJwtUsername(jwt: string): string {\n try {\n const payload = jwt.split('.')[1];\n const claims = JSON.parse(\n Buffer.from(payload, 'base64url').toString('utf8'),\n ) as Record<string, unknown>;\n const raw = claims.sub ?? claims.preferred_username ?? claims.username;\n return typeof raw === 'string'\n ? raw\n : `<non-string:${JSON.stringify(raw)}>`;\n } catch {\n return '<decode-error>';\n }\n}\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse,\n) {\n // oxlint-disable-next-line no-unused-vars\n const action = req.query.action?.[0];\n\n // Intercept res.send to capture response body for logging\n // oxlint-disable-next-line no-unused-vars\n let capturedBody = '';\n const originalSend = res.send.bind(res) as typeof res.send;\n res.send = (body: unknown) => {\n capturedBody = (\n typeof body === 'string' ? body : JSON.stringify(body)\n ).slice(0, 300);\n return originalSend(body);\n };\n\n await upstreamHandler(req, res);\n}\n\nexport const config = { api: { bodyParser: false } };\n"],"names":["GEN3_HATCHERY_API","GEN3_WORKSPACE_API","process","env","GEN3_KERNEL_API","GEN3_API","JEG_GATEWAY_API","JEG_SERVICE_API","extractTokenFallback","req","auth","headers","startsWith","slice","trim","cookie","m","match","decodeURIComponent","MAX_JWT_LENGTH","decodeJwtClaims","jwt","length","parts","split","padded","replace","padEnd","Math","ceil","JSON","parse","Buffer","from","toString","createProxyRequest","res","targetUrl","method","extraHeaders","forwardBody","body","buf","bufferBody","err","statusCode","msg","Error","message","status","json","error","String","upRes","fetch","signal","AbortSignal","timeout","contentType","get","setHeader","end","errBody","text","catch","console","responseBody","send","MAX_BODY_BYTES","Promise","resolve","reject","chunks","total","on","chunk","destroy","Object","assign","push","concat","MAX_FILE_SIZE_BYTES","ALLOWED_TIERS","Set","SAFE_SEGMENT_RE","MIME_TYPES","DEFAULT_FULL_THEMES_URL","SERVER_EXTENSION_PREFIXES","REMOTE_DISABLED_EXTENSIONS","ASSETS_ROOT_PATH","JUPYTER_ASSETS_ROOT_PATH","defaultAssetRoot","nodePath","join","cwd","DEFAULT_REMOTE_BRANDING","appName","faviconUrl","escapeHtml","replaceTitle","html","branding","title","pageTitle","resolveOrigin","forwardedProto","Array","isArray","forwardedHost","hostHeader","host","refererHeader","referer","resolvedHost","resolvedProto","refererUrl","URL","includes","protocol","proto","injectRemoteConfig","config","gatewayBaseUrl","disabledExtensions","fullThemesUrl","remoteKernelsPath","absoluteGatewayBase","accessToken","undefined","NODE_ENV","getCookie","configData","remoteBaseUrl","remoteToken","exposeAppInBrowser","remoteKernelsBaseUrl","result","_match","openTag","existingJson","closeTag","existing","merged","combined","stringify","injectBranding","warn","readBody","proxyServerExtension","getToken","forwardHeaders","key","value","entries","lower","toLowerCase","claims","rawUsername","sub","preferred_username","username","safeUsername","safeJwt","toUpperCase","startedAt","Date","now","parsed","transport","https","http","reqOptions","hostname","port","path","pathname","search","proxyReq","request","proxyRes","skip","has","log","pipe","code","headersSent","write","createWorkspaceAssetsHandler","options","JUPYTER_GATEWAY_BASE_URL","assetRoot","additionalDisabledExtensions","serverExtensionProxyPath","serverExtensionProxyBaseUrl","remoteInjectionConfig","walkDir","dir","set","entry","fs","readdirSync","withFileTypes","full","name","isDirectory","add","allowedFilesByTier","free","remote","tier","handler","pathSegments","query","segments","tierRoot","safeSegments","seg","test","basename","extensionPath","rawQuery","url","qs","proxyBase","allowedFiles","candidatePath","candidateIndex","filePath","ext","extname","isBuildAsset","cookies","encodeURIComponent","isRemoteLabHtml","readFileSync","injected","isHtmlResponse","stat","statSync","size","stream","createReadStream","DEFAULT_WORKSPACE_ROUTES","withJupyterWorkspaces","nextConfig","workspaceRoutes","transpilePackages","filter","pkg","webpack","ctx","alias","react","dirname","require","rewrites","isDev","gatewayProxyUrl","GATEWAY_PROXY_URL","gatewayRewrite","source","destination","beforeFiles","coopCoepHeaders","map","route","defaultBillingSink","event","stdout","type","EMPTY_FENCE_CREDS","key_id","api_key","fetchFenceCreds","fenceUrl","parsedFenceUrl","response","fetchFence","endpoint","Authorization","data","filterAndAnnotateSpecs","raw","policy","allowedSpecs","costPerHour","displayNames","nodeType","filteredSpecs","specName","rawSpec","kernelspecs","spec","display_name","metadata","filteredDefault","default","buildAmbassadorUrl","gen3Endpoint","kernelPath","base","origin","KERNEL_ID_RE","SIMPLE_ROUTES","Map","resolveKernelRoute","actionSegments","seg1","seg2","kernelId","rest","errMsg","handleKernelSpecs","upstream","ambassadorHeaders","ok","statusText","rawSpecs","kernelSpecPolicy","handleKernelsList","handleReap","listUpstream","kernelList","listRes","idleKillMins","idleKillDays","maxAgeMins","maxKernelAgeDays","reaped","errors","kernel","id","lastActivity","last_activity","getTime","idleMins","Infinity","deleteUpstream","sink","action","costTier","timestamp","toISOString","handleKernelLaunch","fenceCreds","rawBody","launchBody","kernelSpec","enrichedBody","GEN3_API_KEY_ID","GEN3_API_KEY_SECRET","NAMESPACE","GEN3_ENDPOINT","launchTimestamp","launchRes","kernelData","handleKernelDelete","handleKernelPassthrough","ALLOWED_FENCE_URLS","GEN3_FENCE_SERVICE","GEN3_FENCE_API","ALLOWED_JEG_URLS","createKernelProxyHandler","billingSink","jegEnabled","kernelLifecycleProxyHandler","rawAction","s","enabled","REMOTE_USER","CONFIG_ROOT","GEN3_FRONTEND_CONFIGURATION_ROOT","CONFIG_FILENAME","DEFAULT_OPTIONS","WORKSPACE_PROXY_URL","getAccessToken","GEN3_COMMONS_NAME","STRING_OPTIONS","configFilePath","parseOptions","extensions","every","loadOptions","file","reason","upstreamHandler","loadedConfigMtimeMs","configMtimeMs","mtimeMs","getUpstreamHandler","ALLOWED_PREFIXES","buildUpstreamPath","clean","Boolean","some","isAllowedPath","prefix","buildQueryString","rawUrl","excludeKey","queryPart","params","URLSearchParams","delete","isBuffer","gatewayUrl","JUPYTER_GATEWAY_URL","gatewayBase","upstreamPath","queryString","Headers","byteLength","Uint8Array","isTimeout","forEach","upstreamContentType","safeContentType","reader","getReader","done","read","releaseLock","inCluster","KUBERNETES_SERVICE_HOST","defaultGen3Endpoint","defaultFenceUrl","KERNEL_SPEC_POLICY","ENABLE_JEG","token","SAFE_ID_RE","resolveHatcheryRoute","routes","ALLOWED_HATCHERY_URLS","createHatcheryProxyHandler","hatcheryProxyHandler","hatcheryUrl","parsedHatcheryUrl","JWT_FORMAT_RE","hatcheryBase","remote_user","defaultHatcheryUrl","originalSend","bind","capturedBody"],"mappings":"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"}