With SSH2 library you'll be able to create a ssh connection to your server to transfer (download and upload) files easily. ssh2 is a SSH2 client module written in pure JavaScript for node.js. As electron framework is able to use node.js, you can use this plugin to create your own sftp client easily.
Requirements
To implement the sftp feature on our hybrid app, we'll need :
- Node.js
- SSH2 (written for Node.js)
- Patience
Now let's get started !
Installation and setup
Add ssh2 as a dependency of your electron project, add it executing the following line in your Node.js command prompt:
npm install ssh2 --save
Then you'll be able to require it with Javascript using require("ssh2");
Creating a SFTP Client
The sftp client will be easy to set up after the installation of the ssh2 library, first you need to create a client (note that ssh2 doesn't support only sftp but more types, ssh ,ftp etc) using :
var Client = require('ssh2').Client;
var connection = new Client();
With the connection now the magic happens, to start a sftp connection, use the following code snippet. A connection object will be prepared and connected using the minimum configuration, then if the ssh connection is succesful, open a sftp connection !
var Client = require('ssh2').Client;
var connSettings = {
host: 'myserver-direction.com',
port: 22, // Normal is 22 port
username: 'myUsername',
password: 'myPassword'
// You can use a key file too, read the ssh2 documentation
};
var conn = new Client();
conn.on('ready', function() {
conn.sftp(function(err, sftp) {
if (err) throw err;
// you'll be able to use sftp here
// Use sftp to execute tasks like .unlink or chmod etc
});
}).connect(connSettings);
Listing a directory
To list a directory use the readdir method :
var Client = require('ssh2').Client;
var connSettings = {
host: 'myserver-direction.com',
port: 22, // Normal is 22 port
username: 'myUsername',
password: 'myPassword'
// You can use a key file too, read the ssh2 documentation
};
var remotePathToList = '/var/www/ourcodeworld';
var conn = new Client();
conn.on('ready', function() {
conn.sftp(function(err, sftp) {
if (err) throw err;
sftp.readdir(remotePathToList, function(err, list) {
if (err) throw err;
// List the directory in the console
console.dir(list);
// Do not forget to close the connection, otherwise you'll get troubles
conn.end();
});
});
}).connect(connSettings);
The list variable is an array with objects, every object contains information about every folder and file inside the remote path. The structure should look like :
Downloading a file
To download a remote file, use the fastGet
method:
var Client = require('ssh2').Client;
var connSettings = {
host: 'myserver-direction.com',
port: 22, // Normal is 22 port
username: 'myUsername',
password: 'myPassword'
// You can use a key file too, read the ssh2 documentation
};
var conn = new Client();
conn.on('ready', function() {
conn.sftp(function(err, sftp) {
if (err) throw err;
var moveFrom = "/remote/file/path/file.txt";
var moveTo = "/local/file/path/file.txt";
sftp.fastGet(moveFrom, moveTo , {}, function(downloadError){
if(downloadError) throw downloadError;
console.log("Succesfully uploaded");
});
});
}).connect(connSettings);
Uploading a file
To upload a file, you'll need to use the createWriteStream
method. It will create a file with the providen name with the content of a local file. To provide the local file we'll use the local filesystem (require("fs")
) and use the createReadStream
method.
var Client = require('ssh2').Client;
var connSettings = {
host: 'myserver-direction.com',
port: 22, // Normal is 22 port
username: 'myUsername',
password: 'myPassword'
// You can use a key file too, read the ssh2 documentation
};
var remotePathToList = '/var/www/ourcodeworld';
var conn = new Client();
conn.on('ready', function() {
conn.sftp(function(err, sftp) {
if (err) throw err;
var fs = require("fs"); // Use node filesystem
var readStream = fs.createReadStream( "path-to-local-file.txt" );
var writeStream = sftp.createWriteStream( "path-to-remote-file.txt" );
writeStream.on('close',function () {
console.log( "- file transferred succesfully" );
});
writeStream.on('end', function () {
console.log( "sftp connection closed" );
conn.close();
});
// initiate transfer of file
readStream.pipe( writeStream );
});
}).connect(connSettings);
Delete a remote file
To delete a file, we'll use the unlink method. This method expects the remote file path as first parameter and a callback.
var Client = require('ssh2').Client;
var connSettings = {
host: 'myserver-direction.com',
port: 22, // Normal is 22 port
username: 'myUsername',
password: 'myPassword'
// You can use a key file too, read the ssh2 documentation
};
var remotePathToList = '/var/www/ourcodeworld';
var conn = new Client();
conn.on('ready', function() {
conn.sftp(function(err, sftp) {
if (err) throw err;
sftp.unlink("remote-filepath.txt", function(err){
if ( err ) {
console.log( "Error, problem starting SFTP: %s", err );
}
else
{
console.log( "file unlinked" );
}
conn.close();
});
});
}).connect(connSettings);
Changing permissions
To change the permissions of a remote file, we'll use the chmod method. This method expects the remote file path as first parameter and the permissions as second parameter, finally the callback as third parameter.
var Client = require('ssh2').Client;
var connSettings = {
host: 'myserver-direction.com',
port: 22, // Normal is 22 port
username: 'myUsername',
password: 'myPassword'
// You can use a key file too, read the ssh2 documentation
};
var remotePathToList = '/var/www/ourcodeworld';
var conn = new Client();
conn.on('ready', function() {
conn.sftp(function(err, sftp) {
if (err) throw err;
sftp.chmod( "remote-file-path.txt", 777, function(err){
if ( err ) {
console.log( "Error, problem starting SFTP: %s", err );
}
else
{
console.log( "Mode changed" );
}
});
});
}).connect(connSettings);
With the previous example the file will have the 777 permissions. (rwxrwxrwx) No restrictions on permissions. Anybody may do anything. Generally not a desirable setting, just an example.
Final notes
There are a couple of details about the plugin that you may need to know:
- The documentation can be found in the README.md file , but only with source code.
- It does not have any kind of tests (unit or integration tests), however it works like a charm and that's important.
Have fun