prisme-flow
Version:
prisme platform flow engine
119 lines (101 loc) • 3.84 kB
JavaScript
/**
* Created by prisme.io on 09/06/2017.
*/
module.exports = function (RED) {
'use strict';
var _ = require('lodash'),
FtpServer = require('ftpd').FtpServer,
ip = require('ip');
RED.nodes.registerType('ftp-server', function (config) {
RED.nodes.createNode(this, config);
var node = this;
var address = ip.address();
node.log('Starting ftp server using ip: ' + address);
var server = new FtpServer(address, {
getInitialCwd: function () {
return '';
},
getRoot: function () {
return '';
},
useWriteFile: true,
useReadFile: true
});
// Based upon this https://github.com/stjohnjohnson/mqtt-camera-ftpd/blob/master/server.js
server.on('client:connected', function (connection) {
var remoteClient = connection.socket.remoteAddress + ':' + connection.socket.remotePort,
usr = '';
node.log('Client connected: ' + remoteClient);
node.status({fill: 'green', shape: 'ring', text: remoteClient});
connection.on('command:user', function (user, success, failure) {
if (!user || user !== node.credentials.username) {
return failure();
}
usr = user;
remoteClient += ' - ' + usr;
success();
});
connection.on('command:pass', function (pass, success, failure) {
if (!pass || pass !== node.credentials.password) {
return failure();
}
node.status({fill: 'green', shape: 'dot', text: remoteClient});
success(usr, newFSHandler());
});
// TODO connection.on('close' ...) doesn't work
connection._onClose = function () {
node.log('Client disconnected: ' + remoteClient);
indicateIdle();
};
connection.on('error', function (error) {
node.error('remoteClient %s had an error: %s', remoteClient, error.toString());
});
});
server.listen(config.port);
node.on('close', function () {
server.close();
});
indicateIdle();
// FUNCTIONS
function indicateIdle() {
node.status({fill: 'blue', shape: 'ring', text: address + ':' + config.port + ' - IDLE'});
}
function newFSHandler() {
var handler = {
writeFile: function (id, file, callback) {
node.log(String.fromCharCode.apply(null, file));
node.send({
topic: id,
payload: file
});
callback();
},
stat: function () {
_.nthArg(-1)(null, {
mode: '0777',
isDirectory: function () {
return true;
},
size: 1,
mtime: 1
});
},
readdir: function (dir, callback) {
callback(null, []);
}
};
['readFile', 'unlink', 'mkdir', 'open', 'close', 'rmdir', 'rename'].forEach(function (method) {
handler[method] = function () {
node.log(method + ' called');
_.nthArg(-1)(new Error(method + ' not implemented'));
}
});
return handler;
}
}, {
credentials: {
username: {type: 'text'},
password: {type: 'password'}
}
});
};