4
4
* See License-AGPL.txt in the project root for license information.
5
5
*/
6
6
7
- import { useState } from "react" ;
7
+ import { useEffect , useState } from "react" ;
8
8
import Modal from "../components/Modal" ;
9
9
import Tooltip from "../components/Tooltip" ;
10
10
import copy from "../images/copy.svg" ;
11
- import AlertBox from "../components/AlertBox " ;
12
- import InfoBox from "../components/InfoBox " ;
11
+ import Alert from "../components/Alert " ;
12
+ import { getGitpodService } from "../service/service " ;
13
13
14
14
function InputWithCopy ( props : { value : string ; tip ?: string ; className ?: string } ) {
15
15
const [ copied , setCopied ] = useState < boolean > ( false ) ;
@@ -35,7 +35,7 @@ function InputWithCopy(props: { value: string; tip?: string; className?: string
35
35
autoFocus
36
36
className = "w-full pr-8 overscroll-none"
37
37
type = "text"
38
- defaultValue = { props . value }
38
+ value = { props . value }
39
39
/>
40
40
< div className = "cursor-pointer" onClick = { ( ) => copyToClipboard ( props . value ) } >
41
41
< div className = "absolute top-1/3 right-3" >
@@ -55,39 +55,46 @@ interface SSHProps {
55
55
}
56
56
57
57
function SSHView ( props : SSHProps ) {
58
- const sshCommand = `ssh '${ props . workspaceId } #${ props . ownerToken } @${ props . ideUrl . replace (
59
- props . workspaceId ,
60
- props . workspaceId + ".ssh" ,
61
- ) } '`;
58
+ const [ hasSSHKey , setHasSSHKey ] = useState ( false ) ;
59
+
60
+ useEffect ( ( ) => {
61
+ getGitpodService ( )
62
+ . server . hasSSHPublicKey ( )
63
+ . then ( ( d ) => {
64
+ setHasSSHKey ( d ) ;
65
+ } )
66
+ . catch ( console . error ) ;
67
+ } , [ ] ) ;
68
+
69
+ const host = props . ideUrl . replace ( props . workspaceId , props . workspaceId + ".ssh" ) ;
70
+ const sshPswCommand = `ssh '${ props . workspaceId } #${ props . ownerToken } @${ host } '` ;
71
+ const sshKeyCommand = `ssh '${ props . workspaceId } @${ host } '` ;
72
+
62
73
return (
63
- < div className = "border-t border-b border-gray-200 dark:border-gray-800 mt-2 -mx-6 px-6 py-6" >
64
- < div className = "mt-1 mb-4" >
65
- < AlertBox >
66
- < p className = "text-red-500 whitespace-normal text-base" >
67
- < b > Anyone</ b > on the internet with this command can access the running workspace. The command
68
- includes a generated access token that resets on every workspace restart.
69
- </ p >
70
- </ AlertBox >
71
- < InfoBox className = "mt-4" >
72
- < p className = "text-gray-500 whitespace-normal text-base" >
73
- Before connecting via SSH, make sure you have an existing SSH private key on your machine. You
74
- can create one using
75
- < a
76
- href = "https://en.wikipedia.org/wiki/Ssh-keygen"
77
- target = "_blank"
78
- rel = "noopener noreferrer"
79
- className = "gp-link"
80
- >
81
- ssh-keygen
82
- </ a >
83
- .
84
- </ p >
85
- </ InfoBox >
86
- < p className = "mt-4 text-gray-500 whitespace-normal text-base" >
74
+ < div >
75
+ < div className = "space-y-4" >
76
+ < Alert type = "warning" className = "whitespace-normal" >
77
+ < b > Anyone</ b > on the internet with this command can access the running workspace. The command
78
+ includes a generated access token that resets on every workspace restart.
79
+ </ Alert >
80
+ < Alert type = "info" className = "whitespace-normal" >
81
+ Before connecting via SSH, make sure you have an existing SSH private key on your machine. You can
82
+ create one using
83
+ < a
84
+ href = "https://en.wikipedia.org/wiki/Ssh-keygen"
85
+ target = "_blank"
86
+ rel = "noopener noreferrer"
87
+ className = "gp-link"
88
+ >
89
+ ssh-keygen
90
+ </ a >
91
+ .
92
+ </ Alert >
93
+ < p className = "text-gray-500 whitespace-normal text-base" >
87
94
The following shell command can be used to SSH into this workspace.
88
95
</ p >
89
96
</ div >
90
- < InputWithCopy value = { sshCommand } tip = "Copy SSH Command" />
97
+ < InputWithCopy className = "my-2" value = { hasSSHKey ? sshKeyCommand : sshPswCommand } tip = "Copy SSH Command" />
91
98
</ div >
92
99
) ;
93
100
}
@@ -99,15 +106,17 @@ export default function ConnectToSSHModal(props: {
99
106
onClose : ( ) => void ;
100
107
} ) {
101
108
return (
102
- // TODO: Use title and buttons props
103
- < Modal visible = { true } onClose = { props . onClose } >
104
- < h3 className = "mb-4" > Connect via SSH</ h3 >
105
- < SSHView workspaceId = { props . workspaceId } ownerToken = { props . ownerToken } ideUrl = { props . ideUrl } />
106
- < div className = "flex justify-end mt-6" >
109
+ < Modal
110
+ title = "Connect via SSH"
111
+ buttons = {
107
112
< button className = { "ml-2 secondary" } onClick = { ( ) => props . onClose ( ) } >
108
113
Close
109
114
</ button >
110
- </ div >
115
+ }
116
+ visible = { true }
117
+ onClose = { props . onClose }
118
+ >
119
+ < SSHView workspaceId = { props . workspaceId } ownerToken = { props . ownerToken } ideUrl = { props . ideUrl } />
111
120
</ Modal >
112
121
) ;
113
122
}
0 commit comments