/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import logger from "../../../logger"; import type WebSocket from "ws"; import { Server as WebSocketServer } from "ws"; import type { ProxyApiRequestArgs } from "../types"; import type { ClusterManager } from "../../../cluster/manager"; import URLParse from "url-parse"; import type { Cluster } from "../../../../common/cluster/cluster"; import type { ClusterId } from "../../../../common/cluster-types"; interface Dependencies { authenticateRequest: (clusterId: ClusterId, tabId: string, shellToken: string | undefined) => boolean; createShellSession: (args: { websocket: WebSocket; cluster: Cluster; tabId: string; nodeName?: string; }) => { open: () => Promise }; clusterManager: ClusterManager; } export const shellApiRequest = ({ createShellSession, authenticateRequest, clusterManager }: Dependencies) => ({ req, socket, head }: ProxyApiRequestArgs): void => { const cluster = clusterManager.getClusterForRequest(req); const { query: { node: nodeName, shellToken, id: tabId }} = new URLParse(req.url, true); if (!tabId || !cluster || !authenticateRequest(cluster.id, tabId, shellToken)) { socket.write("Invalid shell request"); return void socket.end(); } const ws = new WebSocketServer({ noServer: true }); ws.handleUpgrade(req, socket, head, (websocket) => { const shell = createShellSession({ websocket, cluster, tabId, nodeName }); shell.open() .catch(error => logger.error(`[SHELL-SESSION]: failed to open a ${nodeName ? "node" : "local"} shell`, error)); }); };