Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using npm package ssh2 within an Angular2 application running under electron

I want to create an Angular2 service which uses the npm package ssh2 - https://www.npmjs.com/package/ssh2.

I have installed and configured it as I would expect - the code for my service can be seen below (this code is based on the first example shown on the ssh2 npm site and github repo(the only change being I am using a password rather than a key for authentication)):

const Client = require('ssh2').Client;
const fs = require('fs');

import { NextObserver } from 'rxjs/Observer';
import { Observable } from 'rxjs/Rx';

export class SSHClient {
    username: string;
    password: string;
    host: string;
    port: number;
    ssh: any;

    constructor() {
    }

    init(username, password, host, port) {
        console.log("initiating SSH connection to:" + host + "on port:" + port);

        this.username = username;
        this.password = password;
        this.host = host;
        this.port = port;


        console.log("Connecting now...");
        var conn = new Client();
        conn.on('ready', function() {
          console.log('Client :: ready');
          conn.exec('uptime', function(err, stream) {
            if (err) throw err;
            stream.on('close', function(code, signal) {
              console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
              conn.end();
            }).on('data', function(data) {
              console.log('STDOUT: ' + data);
            }).stderr.on('data', function(data) {
              console.log('STDERR: ' + data);
            });
          });
        }).connect({
          host: this.host,
          port: this.port,
          username: this.username,
          password: this.password
        });
        console.log("SSH Client created and demo has run");
    }

}

I make my call to the service as per this from within my component:

this.ssh.init("username","password","my.little.host",22);

And I expect to get back the output of the uptime command having executed over SSH on my server - via the console. However instead of that - I get this:

EXCEPTION: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
    at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
    at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
    at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
    at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
    at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
    at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
    at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
    at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
    at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
    at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
ORIGINAL STACKTRACE:
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
    at SSHClient.init (ssh.service.ts:49)
    at new ServerBrowserComponent (server.browser.component.ts:31)
    at new Wrapper_ServerBrowserComponent (wrapper.ngfactory.js:7)
    at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (host.ngfactory.js:16)
    at DebugAppView.AppView.create (core.umd.js:9170)
    at DebugAppView.create (core.umd.js:9370)
    at ComponentFactory.create (core.umd.js:5809)
    at ViewContainerRef_.createComponent (core.umd.js:4857)
    at RouterOutlet.activate (router.umd.js:3457)
    at ActivateRoutes.placeComponentIntoOutlet (router.umd.js:2955)
    at resolvePromise (zone-node.js:468)
    at zone-node.js:445
    at ZoneDelegate.invoke (zone-node.js:232)
    at Object.onInvoke (core.umd.js:6206)
    at ZoneDelegate.invoke (zone-node.js:231)
    at Zone.run (zone-node.js:114)
    at zone-node.js:502
    at ZoneDelegate.invokeTask (zone-node.js:265)
    at Object.onInvokeTask (core.umd.js:6197)
    at ZoneDelegate.invokeTask (zone-node.js:264)
Unhandled Promise rejection: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined ; Zone: angular ; Task: Promise.then ; Value: ViewWrappedError TypeError: Cannot read property 'connect' of undefined
    at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
    at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
    at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
    at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
    at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
    at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
    at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
    at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
    at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
    at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined(…)

The bulk of that seems to be struggling because : Cannot read property 'connect' of undefined -- yet I am following the example documentation. Can somebody please help my understand why this is not working - and how I can fix it?

I tried to pull the code out of my project and into its own file which looks like:

    const Client = require('ssh2').Client; 
console.log("Connecting now...");
         var conn = new Client();
         conn.on('ready', function() {
          console.log('Client :: ready');
          conn.exec('uptime', function(err, stream) {
            if (err) throw err;
            stream.on('close', function(code, signal) {
                 console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
                  conn.end();
            }).on('data', function(data) {
                  console.log('STDOUT: ' + data);
            }).stderr.on('data', function(data) {
                  console.log('STDERR: ' + data);
            });
          });
       }).connect({
          host: 'my.little.host',
          port: 22,
          username: 'uname',
          password: 'pwd'
        });
         console.log("SSH Client created and demo has run");

But I get the same error:

 var conn = new Client();
                ^

ReferenceError: Client is not defined
    at Object.<anonymous> (/Users/myapp/attempt.js:2:21)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3

So something simple is going wrong here, what could it be!?

like image 532
RenegadeAndy Avatar asked Feb 26 '26 15:02

RenegadeAndy


1 Answers

the ssh2-package is for node.js, not frontend/web.

The browser can't use network like that (electron uses two processes, the browser/renderer -process does not have access to the network features you need)

does your electron app have a main.js file?

that's where you need to implement the ssh functionality.

i.e. in the main-process, not in the renderer-process.

http://electron.atom.io/docs/tutorial/quick-start/#main-process

like image 109
Johan Blomgren Avatar answered Mar 01 '26 08:03

Johan Blomgren