2016-04-07 19:22:13 -06:00
'use strict' ;
var _createClass = function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ( ) ;
var _child _process = require ( 'child_process' ) ;
var _events = require ( 'events' ) ;
2016-04-08 10:48:25 -06:00
var _portfinder = require ( 'portfinder' ) ;
var _portfinder2 = _interopRequireDefault ( _portfinder ) ;
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
2016-04-07 19:22:13 -06:00
function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
function _possibleConstructorReturn ( self , call ) { if ( ! self ) { throw new ReferenceError ( "this hasn't been initialised - super() hasn't been called" ) ; } return call && ( typeof call === "object" || typeof call === "function" ) ? call : self ; }
function _inherits ( subClass , superClass ) { if ( typeof superClass !== "function" && superClass !== null ) { throw new TypeError ( "Super expression must either be null or a function, not " + typeof superClass ) ; } subClass . prototype = Object . create ( superClass && superClass . prototype , { constructor : { value : subClass , enumerable : false , writable : true , configurable : true } } ) ; if ( superClass ) Object . setPrototypeOf ? Object . setPrototypeOf ( subClass , superClass ) : subClass . _ _proto _ _ = superClass ; }
2016-04-08 01:35:38 -06:00
/ * A u t o S S H c l a s s
* /
2016-04-07 19:22:13 -06:00
2016-04-08 01:35:38 -06:00
var AutoSSH = function ( _EventEmitter ) {
_inherits ( AutoSSH , _EventEmitter ) ;
function AutoSSH ( ) {
2016-04-07 19:22:13 -06:00
var conf = arguments . length <= 0 || arguments [ 0 ] === undefined ? { } : arguments [ 0 ] ;
2016-04-08 01:35:38 -06:00
_classCallCheck ( this , AutoSSH ) ;
2016-04-07 19:22:13 -06:00
2016-04-08 01:35:38 -06:00
var _this = _possibleConstructorReturn ( this , Object . getPrototypeOf ( AutoSSH ) . call ( this ) ) ;
2016-04-07 19:22:13 -06:00
_this . host = conf . host ;
_this . username = conf . username ;
_this . remotePort = conf . remotePort ;
_this . localPort = conf . localPort ;
setImmediate ( function ( ) {
if ( ! conf . localPort ) return _this . emit ( 'error' , 'Missing localPort' ) ;
2016-04-08 14:28:58 -06:00
_portfinder2 . default . getPort ( {
port : _this . localPort === 'auto' ? _this . generateRandomPort ( ) : _this . localPort
} , function ( err , freePort ) {
if ( err ) return _this . emit ( 'error' , 'Port error: ' + err ) ;
if ( _this . localPort !== 'auto' && _this . localPort !== freePort ) return _this . emit ( 'error' , 'Port ' + _this . localPort + ' is not available' ) ;
if ( ! conf . host ) return _this . emit ( 'error' , 'Missing host' ) ;
if ( ! conf . username ) return _this . emit ( 'error' , 'Missing username' ) ;
if ( ! conf . remotePort ) return _this . emit ( 'error' , 'Missing remotePort' ) ;
_this . localPort = freePort ;
_this . execTunnel ( ) ;
_this . emit ( 'connect' , {
kill : _this . kill ,
pid : _this . currentProcess . pid ,
host : _this . host ,
username : _this . username ,
remotePort : _this . remotePort ,
localPort : _this . localPort
} ) ;
} ) ;
2016-04-08 01:35:38 -06:00
} ) ;
process . on ( 'exit' , function ( ) {
_this . kill ( ) ;
2016-04-07 19:22:13 -06:00
} ) ;
return _this ;
}
2016-04-08 01:35:38 -06:00
_createClass ( AutoSSH , [ {
2016-04-08 14:28:58 -06:00
key : 'generateRandomPort' ,
value : function generateRandomPort ( ) {
var minPort = 3000 ;
var maxPort = 65535 ;
return Math . floor ( Math . random ( ) * ( maxPort - minPort + 1 ) ) + minPort ;
}
} , {
2016-04-07 19:22:13 -06:00
key : 'execTunnel' ,
value : function execTunnel ( ) {
var _this2 = this ;
2016-04-08 01:35:38 -06:00
var bindAddress = this . localPort + ':localhost:' + this . remotePort ;
var userAtHost = this . username + '@' + this . host ;
var exitOnFailure = '-o "ExitOnForwardFailure yes"' ;
var execString = 'ssh -NL ' + bindAddress + ' ' + exitOnFailure + ' ' + userAtHost ;
2016-04-08 14:28:58 -06:00
2016-04-08 01:35:38 -06:00
this . currentProcess = ( 0 , _child _process . exec ) ( execString , function ( err , stdout , stderr ) {
if ( /Address already in use/i . test ( stderr ) ) {
_this2 . kill ( ) ;
return _this2 . emit ( 'error' , stderr ) ;
}
2016-04-07 19:22:13 -06:00
if ( err ) _this2 . emit ( 'error' , err ) ;
2016-04-08 01:35:38 -06:00
if ( ! _this2 . killed ) {
console . log ( 'Restarting autossh...' ) ;
_this2 . execTunnel ( ) ;
}
2016-04-07 19:22:13 -06:00
} ) ;
}
} , {
key : 'kill' ,
value : function kill ( ) {
this . killed = true ;
this . currentProcess . kill ( ) ;
return this ;
}
} ] ) ;
2016-04-08 01:35:38 -06:00
return AutoSSH ;
2016-04-07 19:22:13 -06:00
} ( _events . EventEmitter ) ;
2016-04-08 01:35:38 -06:00
function autoSSH ( conf ) {
var newAutoSSH = new AutoSSH ( conf ) ;
var returnObj = {
on : function on ( evt ) {
for ( var _len = arguments . length , args = Array ( _len > 1 ? _len - 1 : 0 ) , _key = 1 ; _key < _len ; _key ++ ) {
args [ _key - 1 ] = arguments [ _key ] ;
}
newAutoSSH . on . apply ( newAutoSSH , [ evt ] . concat ( args ) ) ;
return this ;
} ,
kill : function kill ( ) {
newAutoSSH . kill ( ) ;
return this ;
}
} ;
Object . defineProperty ( returnObj , 'pid' , {
get : function get ( ) {
return newAutoSSH . currentProcess . pid ;
}
} ) ;
return returnObj ;
2016-04-07 19:22:13 -06:00
}
2016-04-08 01:35:38 -06:00
module . exports = autoSSH ;