Path: blob/main/components/dashboard/src/workspaces/ConnectToSSHModal.tsx
2500 views
/**1* Copyright (c) 2022 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56import { useEffect, useState } from "react";7import Modal, { ModalBody, ModalFooter, ModalHeader } from "../components/Modal";8import Alert from "../components/Alert";9import { settingsPathSSHKeys } from "../user-settings/settings.routes";10import { InputWithCopy } from "../components/InputWithCopy";11import { Link } from "react-router-dom";12import { Button } from "@podkit/buttons/Button";13import { sshClient } from "../service/public-api";14import { Tabs, TabsContent, TabsList, TabsTrigger } from "@podkit/tabs/Tabs";1516interface SSHProps {17workspaceId: string;18ownerToken: string;19ideUrl: string;20}2122function SSHView(props: SSHProps) {23const [hasSSHKey, setHasSSHKey] = useState(true);2425useEffect(() => {26sshClient27.listSSHPublicKeys({})28.then((r) => {29setHasSSHKey(r.sshKeys.length > 0);30})31.catch(console.error);32}, []);3334const host = props.ideUrl.replace(props.workspaceId, props.workspaceId + ".ssh");35const sshAccessTokenCommand = `ssh '${props.workspaceId}#${props.ownerToken}@${host}'`;36const sshKeyCommand = `ssh '${props.workspaceId}@${host}'`;3738return (39<>40<Tabs defaultValue="ssh_key">41<TabsList className="flex flex-row items-start">42<TabsTrigger value="ssh_key" className="text-base">43{" "}44SSH Key{" "}45</TabsTrigger>46<TabsTrigger value="access_token" className="text-base">47Access Token48</TabsTrigger>49</TabsList>50<div className="border-gray-200 dark:border-gray-800 pt-1 border-b"></div>51<TabsContent value="ssh_key" className="space-y-4 mt-4">52{!hasSSHKey && (53<Alert type="warning" className="whitespace-normal">54You don't have any public SSH keys in your Gitpod account. You can{" "}55<Link to={settingsPathSSHKeys} className="gp-link">56add a new public key57</Link>58, or use a generated access token.59</Alert>60)}6162<p className="text-gray-500 whitespace-normal text-base">63<span>64The following shell command can be used to SSH into this workspace with an{" "}65<Link to={settingsPathSSHKeys} className="gp-link">66SSH key67</Link>68.69</span>70</p>71<InputWithCopy className="my-2" value={sshKeyCommand} tip="Copy SSH Command" />72</TabsContent>73<TabsContent value="access_token" className="space-y-4 mt-4">74<Alert type="warning" className="whitespace-normal">75<b>Anyone</b> on the internet with this command can access the running workspace. The command76includes a generated access token that resets on every workspace restart.77</Alert>78<p className="text-gray-500 whitespace-normal text-base">79The following shell command can be used to SSH into this workspace.80</p>81<InputWithCopy className="my-2" value={sshAccessTokenCommand} tip="Copy SSH Command" />82</TabsContent>83</Tabs>84</>85);86}8788export default function ConnectToSSHModal(props: {89workspaceId: string;90ownerToken: string;91ideUrl: string;92onClose: () => void;93}) {94return (95<Modal hideDivider visible onClose={props.onClose}>96<ModalHeader>Connect via SSH</ModalHeader>97<ModalBody>98<SSHView workspaceId={props.workspaceId} ownerToken={props.ownerToken} ideUrl={props.ideUrl} />99</ModalBody>100<ModalFooter>101<Button variant="secondary" onClick={() => props.onClose()}>102Close103</Button>104</ModalFooter>105</Modal>106);107}108109110