From 924b20eaee81481451a163f996cf7d7a8e4b51ab Mon Sep 17 00:00:00 2001 From: mustard Date: Wed, 15 Jun 2022 16:58:31 +0000 Subject: [PATCH] [dashboard] support ssh copy-paste with ssh keys --- components/dashboard/src/components/Modal.tsx | 8 +- .../src/workspaces/ConnectToSSHModal.tsx | 121 ++++++++++++------ 2 files changed, 91 insertions(+), 38 deletions(-) diff --git a/components/dashboard/src/components/Modal.tsx b/components/dashboard/src/components/Modal.tsx index c6e3f6b8cd..df1a4e65d0 100644 --- a/components/dashboard/src/components/Modal.tsx +++ b/components/dashboard/src/components/Modal.tsx @@ -13,6 +13,7 @@ export default function Modal(props: { // specify a key if having the same title and window.location specify?: string; title?: string; + hideDivider?: boolean; buttons?: React.ReactChild[] | React.ReactChild; children: React.ReactChild[] | React.ReactChild; visible: boolean; @@ -94,7 +95,12 @@ export default function Modal(props: { {props.title ? ( <>

{props.title}

-
+
{props.children}
{props.buttons}
diff --git a/components/dashboard/src/workspaces/ConnectToSSHModal.tsx b/components/dashboard/src/workspaces/ConnectToSSHModal.tsx index 39ee961f22..5e03667043 100644 --- a/components/dashboard/src/workspaces/ConnectToSSHModal.tsx +++ b/components/dashboard/src/workspaces/ConnectToSSHModal.tsx @@ -4,12 +4,14 @@ * See License-AGPL.txt in the project root for license information. */ -import { useState } from "react"; +import { useEffect, useState } from "react"; import Modal from "../components/Modal"; import Tooltip from "../components/Tooltip"; import copy from "../images/copy.svg"; -import AlertBox from "../components/AlertBox"; -import InfoBox from "../components/InfoBox"; +import Alert from "../components/Alert"; +import TabMenuItem from "../components/TabMenuItem"; +import { settingsPathSSHKeys } from "../settings/settings.routes"; +import { getGitpodService } from "../service/service"; function InputWithCopy(props: { value: string; tip?: string; className?: string }) { const [copied, setCopied] = useState(false); @@ -35,7 +37,7 @@ function InputWithCopy(props: { value: string; tip?: string; className?: string autoFocus className="w-full pr-8 overscroll-none" type="text" - defaultValue={props.value} + value={props.value} />
copyToClipboard(props.value)}>
@@ -55,40 +57,80 @@ interface SSHProps { } function SSHView(props: SSHProps) { - const sshCommand = `ssh '${props.workspaceId}#${props.ownerToken}@${props.ideUrl.replace( - props.workspaceId, - props.workspaceId + ".ssh", - )}'`; + const [hasSSHKey, setHasSSHKey] = useState(true); + const [selectSSHKey, setSelectSSHKey] = useState(true); + + useEffect(() => { + getGitpodService() + .server.hasSSHPublicKey() + .then((d) => { + setHasSSHKey(d); + }) + .catch(console.error); + }, []); + + const host = props.ideUrl.replace(props.workspaceId, props.workspaceId + ".ssh"); + const sshAccessTokenCommand = `ssh '${props.workspaceId}#${props.ownerToken}@${host}'`; + const sshKeyCommand = `ssh '${props.workspaceId}@${host}'`; + return ( -
-
- -

+ <> +

+ { + setSelectSSHKey(true); + }} + /> + { + setSelectSSHKey(false); + }} + /> +
+
+
+ {!selectSSHKey && ( + Anyone on the internet with this command can access the running workspace. The command includes a generated access token that resets on every workspace restart. -

- - -

- Before connecting via SSH, make sure you have an existing SSH private key on your machine. You - can create one using  - - ssh-keygen + + )} + {!hasSSHKey && selectSSHKey && ( + + You don't have any public SSH keys in your Gitpod account. You can{" "} + + add a new public key - . -

-
-

- The following shell command can be used to SSH into this workspace. + , or use a generated access token. + + )} + +

+ {!selectSSHKey ? ( + "The following shell command can be used to SSH into this workspace." + ) : ( + <> + The following shell command can be used to SSH into this workspace with a{" "} + + ssh key + + . + + )}

- -
+ + ); } @@ -99,14 +141,19 @@ export default function ConnectToSSHModal(props: { onClose: () => void; }) { return ( - // TODO: Use title and buttons props - -

Connect via SSH

- -
+ props.onClose()}> Close + } + visible={true} + onClose={props.onClose} + > +
+
);