import React from 'react' ; import cfg from 'teleport/config' ; import { Session } from 'teleport/services/ssh' ; import { TermEventEnum } from 'teleport/lib/term/enums' ; import Tty from 'teleport/lib/term/tty' ; import ConsoleContext from 'teleport/Console/consoleContext' ; import { useConsoleContext } from 'teleport/Console/consoleContextProvider' ; import { DocumentSsh } from 'teleport/Console/stores' ; export default function useSshSession ( doc ) { const { clusterId , sid , serverId , login } = doc ; const ctx = useConsoleContext ( ) ; const ttyRef = React . useRef < Tty > ( null ) ; const tty = ttyRef . current as ReturnType < typeof ctx . createTty > ; const [ session , setSession ] = React . useState < Session > ( null ) ; const [ statusText , setStatusText ] = React . useState ( '' ) ; const [ status , setStatus ] = React . useState < Status > ( 'loading' ) ; function closeDocument ( ) { ctx . closeTab ( doc ) ; } React . useEffect ( ( ) => { function initTty ( session ) { const tty = ctx . createTty ( session ) ; tty . on ( TermEventEnum . CLOSE , ( ) => ctx . closeTab ( doc ) ) ; tty . on ( TermEventEnum . CONN_CLOSE , ( ) => ctx . updateSshDocument ( doc . id , { status : 'disconnected' } ) ) ; tty . on ( 'open' , ( ) => handleTtyConnect ( ctx , session , doc . id ) ) ; ttyRef . current = tty ; setSession ( session ) ; setStatus ( 'initialized' ) ; } function cleanup ( ) { ttyRef . current && ttyRef . current . removeAllListeners ( ) ; } if ( sid ) { ctx . fetchSshSession ( clusterId , sid ) . then ( initTty ) . catch ( err => { setStatus ( 'notfound' ) ; setStatusText ( err . message ) ; } ) ; } else { ctx . createSshSession ( clusterId , serverId , login ) . then ( initTty ) . catch ( err => { setStatus ( 'error' ) ; setStatusText ( err . message ) ; } ) ; } return cleanup ; } , [ ] ) ; return { tty , status , statusText , session , closeDocument , } ; } function handleTtyConnect ( ctx , session , docId ) { const { hostname , login , sid , clusterId } = session ; const url = cfg . getSshSessionRoute ( { sid , clusterId } ) ; ctx . updateSshDocument ( docId , { title : `${ login }@${ hostname }` , status : 'connected' , url , ... session , } ) ; ctx . gotoTab ( { url } ) ; } type Status = 'initialized' | 'loading' | 'notfound' | 'error' ;