ssh2 nodejs | upload file to sftp | Error: Permission denied at 101 - javascript

When trying to upload a file to sftp server permission denied error appears. The same operation works if file is transferred via FilezIlla.
const UploadFiletoFTP = () => {
let Client = require('ssh2').Client;
var connSettings = {
host: 'abc.com',
port: 22,
username: 'user',
password: 'pass',
};
var conn = new Client();
conn
.on('ready', function () {
conn.sftp(function (err, sftp) {
try {
if (err) {
console.log(err);
throw 'error ' + err;
}
console.log('connected');
var fs = require('fs'); // Use node filesystem
var readStream = fs.createReadStream(
require('path').join(
__dirname +
'/audio/test_data_25_05_2022_09_58_00.zip'
)
);
sftp.readdir(
'speech/non-english',
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();
}
);
var writeStream = sftp.createWriteStream('SpeechIQ', {
flags: 'a', // w - write and a - append
encoding: null, // use null for binary files
mode: 0o666, // mode to use for created file (rwx)
});
writeStream.on('close', function () {
console.log('- file transferred succesfully');
});
writeStream.on('end', function () {
console.log('sftp connection closed');
conn.end();
});
readStream.pipe(writeStream);
} catch (err) {
console.error(err);
}
});
})
.connect(connSettings);
};
UploadFiletoFTP();
When the above code is run below error appears:
events.js:377
throw er; // Unhandled 'error' event
^
Error: Permission denied
at 101
Emitted 'error' event on Client instance at:
.
.
.
.
code: 3
}
Please advise if I am missing something.
Below snippet lists the files in the directory but the writestream is not working.
sftp.readdir(
'speech/non-english',
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();
}
);

I had to give the filename to which the data has to be uploaded
var writeStream = sftp.createWriteStream('SpeechIQ/filename.zip', {
flags: 'a', // w - write and a - append
encoding: null, // use null for binary files
mode: 0o666, // mode to use for created file (rwx)
});

Related

Fluent-ffmpeg Invalid data found when processing input error only when the second request is received

I am using Node.js for backend to use ffmpeg. To use ffmpeg, I adopted fluent-ffmpeg. This is working perfectly except for one problem. That is when I send video from client side SPA(single page application) to the server-side for the "second" time, node application crashes.
What I did is saving the received video in the backend folder, which is made in the process, and taking a snapshot of the video.
This code actually works everytime after restarting the server, but once I used this route and try another time, the error message "Invalid data found when processing input video ./received/${receivedName}" comes up.
app.post("/convert", fileUpload({ createParentPath: true }), async function (req, res) {
makeDir(receivedVideoDirectory);
const receivedName = Object.keys(req.files)[0];
const directoryName = receivedName.substring(0, receivedName.indexOf("."));
const receivedFile = req.files[receivedName];
transcodedSegFolder = `./public/transcoded/${dirName}`;
console.log("transcoded segment file folder is here", transcodedSegFolder);
makeDir(transcodedSegFolder);
fs.open(`./received/${receivedName}`, 'w', (err, fd) => {
if (err) throw err;
fs.writeFile(fd, receivedFile["data"], function (err) {
if (err) {
return console.log("Err in write file ", err);
}
console.log("The file was saved!", receivedName);
fs.close(fd, (err) => {
if (err) throw err;
});
});
});
ffmpeg(`./received/${receivedName}`)
.takeScreenshots(
{
count: 1,
timemarks: ['00:00:01.000'],
folder: './public/thumbnails',
filename: dirName
}).on('error', function(err) {
console.log('screenshot error happened: ' + err.message);
}).on('end', function(err) {
console.log('Screenshot process finished: ');
});
Probably some program keeps working, but I cannot find it. Any help is appreciated. Thank you.

Node.js SFTP error > Error: connect: An existing SFTP connection is already defined

Within my node.js application I am using ssh2-sftp-client to upload an image every 5 seconds.
The upload is working, however when repeating the function, I get the error message
node .\upload.js
uploaded screenshot to server as test_screenshot_uploadI3Mjc.png (first run)
Error: connect: An existing SFTP connection is already defined (second run)
My code is:
let Client = require('ssh2-sftp-client');
let sftp = new Client();
function uploadScreenshot() {
randomNumber = Buffer.from(Math.random().toString()).toString("base64").substring(10,15);
filename = "test_screenshot_upload"+randomNumber+".png";
sftp.connect({
host: 'ssh.strato.de',
port: '22',
username: 'user',
password: 'pass'
}).then(() => {
sftp.put('screenshot.png', '/path/folder/folder/'+filename);
}).then(data => {
console.log("uploaded screenshot to server as " + filename);
}).catch(err => {
console.log(err, 'catch error');
});
}
function foo() {
uploadScreenshot();
setInterval(foo, 5000);
}
foo();
I tried to add sftp.end(); after sftp.put, but this did not help. Could you give me a hint on what I have done incorrectly?
All I needed to do was move
let sftp = new Client();
into
function uploadScreenshot()
It's now working.

Post request not working on plesk while working on localhost

What I'm trying to do:
I'm trying to make a api that saves images. I'd send a post request to the api with the image in body and it saves to the static folder 'public/images'.
Problem: I tried to do this on localhost and it works perfectly. I've got the cross-origin error's before but I've fixed them. After I hosted the api on plesk, it doesn't save the image, or send a error message back. I've checked the logs on plesk and it says that it received the post request. but it's not doing anything with it.
front-end code on client-side (hosted on plesk):
const formData = new FormData();
var fileField = document.querySelector('input[type="file"]');
formData.append('image', fileField.files[0]);
const result = await fetch('https://cdn.dhulun.com/upload25single', {
method: 'POST',
body: formData
}).then(res => res.json())
if (result.status === "ok") {
console.log("Success");
window.location.href = '/';
} else if (result.status === "error") {
console.log("error", result.error)
} else {
console.log("Something went wrong...")
}
back-end code on api (hosted on plesk):
const express = require('express');
const multer = require('multer');
const path = require('path');
const dotenv = require('dotenv');
const mongoose = require('mongoose');
const cors = require('cors')
dotenv.config();
// CONNECT TO DATABASE
async function connectDB() {
await mongoose.connect(process.env.DB_CONNECT,
{ useNewUrlParser: true, useUnifiedTopology: true },
() => {
console.log("Connected to Portal Base [Server]")
});
}
connectDB();
var Media = require('./models/media')
// INIT APP
const app = express();
app.use(cors())
// STATIC FILES
app.use(express.static(__dirname + '/public'));
app.use('/image', express.static('./public/images'))
// RULES
// INIT MULTER
// Storage Engine
const storage = multer.diskStorage({
destination: './public/images',
filename: (req, file, cb) => {
return cb(null, `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`)
}
})
const upload = multer({
storage: storage,
limits: { fileSize: 8000000 },
})
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
});
app.post('/upload25single', upload.single('image'), async(req, res) => {
var image_url = `http://localhost:2525/image/${req.file.filename}`;
console.log({
status: 'ok',
image_url: image_url,
})
res.json({
status: 'ok',
image_url: image_url,
});
/* var location = req.body.location;
var category = req.body.category;
var sourceby = req.body.sourceby;
var tags = req.body.tags;
const media = new Media({
url: image_url,
location: location,
category: category,
source_by: sourceby,
tags: tags
});
try {
const saved = await media.saved();
res.json({
status: 'ok',
image_url: image_url,
});
} catch (error) {
res.json({
status: 'error',
err: error,
});
}
*/
})
function errHandler(err, req, res, next) {
if (err instanceof multer.MulterError) {
res.json({
status: 'error',
err: err.message
})
}
}
// ERROR HANDLING
app.use(errHandler)
app.listen(process.env.PORT || 2525, () => console.log("Server Started..."));
I get this error on the browser console (hosted on plesk): Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
When i click the code line number in the log i got sent to this line:
console.log("Something went wrong...")
EDIT: I got suggested to turn res.json() to res.text() and i got this:
<p>iisnode encountered an error when processing the request.</p><pre style="background-color: eeeeee">HRESULT: 0x6d
HTTP status: 500
HTTP subStatus: 1013
HTTP reason: Internal Server Error</pre><p>You are receiving this HTTP 200 response because <a href=https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config>system.webServer/iisnode/#devErrorsEnabled</a> configuration setting is 'true'.</p><p>In addition to the log of stdout and stderr of the node.exe process, consider using <a href=http://tomasz.janczuk.org/2011/11/debug-nodejs-applications-on-windows.html>debugging</a> and <a href=http://tomasz.janczuk.org/2011/09/using-event-tracing-for-windows-to.html>ETW traces</a> to further diagnose the problem.</p><p>The last 64k of the output generated by the node.exe process to stderr is shown below:</p><pre style="background-color: eeeeee">(node:7696) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
Using Node.Js: Express & Multer

How can I wait a Python shell to execute before serving file

I've an express server route which receives a xml file, then parses and return it as json.
When a user sends a file, it saves in a directory './upload', parses it with a Python script then output json in './json-output', which is served.
When I first upload a file, the response comes empty. But when I do the same upload steps (there is a json already created from last upload on './json-output' dir), it serves the json. It seems some asynchronous issue but I couldn't fix it.
app.post('/upload', function(req, res) {
upload(req, res, async function(err) {
if (err) {
res.json({ error_code: 1, err_desc: err });
return;
}
if (!req.file) {
res.json({ error_code: 1, err_desc: 'No file passed' });
return;
}
let fileName = req.file.originalname;
const options = {
args: [ fileName ]
};
const parserPath = path.join(__dirname + '/parser/parser.py');
const readFile = promisify(PythonShell.run);
await readFile(parserPath, options);
fileName = fileName.split('.')[0];
res.sendFile(path.join(__dirname + `/json-output/${fileName}.json`));
});
});
I'm running it inside a docker images
This a quite a "Dirty fix" in my eyes but you could do a while loop EG:
fileName = fileName.split('.')[0];
while (!fs.existsSync(path.join(__dirname + `/json-output/${fileName}.json`)){
console.log('File does not exist!')
}
//Becareful you should delete the file once the res.send is done
res.sendFile(path.join(__dirname + `/json-output/${fileName}.json`));
Decided to read the python-shell docs here an idea:
https://www.npmjs.com/package/python-shell#exchanging-data-between-node-and-python
So, in theory, you can start a new
let pyshell = new PythonShell(path.join(__dirname + '/parser/parser.py'),options);
pyshell.end(function (err,code,signal) {
if (err) throw err;
fileName = fileName.split('.')[0];
res.sendFile(path.join(__dirname + `/json-output/${fileName}.json`));
});

SSH into remote machine and execute commands in Node.js

I'm looking for a way to SSH into a virtual machine and then execute certain scripts inside the virtual machine using Node.js
So far I've created the shell script that automate the login to the virtual machine but i'm unable to figure out how to move forward.
My shell script for login to remote server
spawn ssh root#localhost
expect "password"
send "123456"
send "\r"
interact
This is my server.js
var http = require('http');
var execProcess = require("./exec_process.js");
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
execProcess.result("sh sshpass.sh", function(err, response){
if(!err){
res.end(response);
}else {
res.end("Error: ", err);
}
});
}).listen(3000);
console.log('Server listening on port 3000');
exec_process.js
var exec = require('child_process').exec;
var result = function(command, cb){
var child = exec(command, function(err, stdout, stderr){
if(err != null){
return cb(new Error(err), null);
}else if(typeof(stderr) != "string"){
return cb(new Error(stderr), null);
}else{
return cb(null, stdout);
}
});
}
exports.result = result;
Any help is appreciated thanks
Why dont you use simple-ssh ?
I made a simple example of how to load a file with a list of commands and execute them in chain.
exampleList : (commands must be separated in new lines)
echo "Testing the first command"
ls
sshtool.js : (it can be buggy, example: if any command contains \n)
const _ = require("underscore");
//:SSH:
const SSH = require('simple-ssh');
const ssh = new SSH({
host: 'localhost',
user: 'username',
pass: 'sshpassword'
});
//example usage : sshtool.js /path/to/command.list
function InitTool(){
console.log("[i] SSH Command Tool");
if(process.argv[2]){AutomaticMode();}
else{console.log("[missing argument : path to file containing the list of commands]");}
}
//:MODE:Auto
function AutomaticMode(){
const CMDFileName = process.argv[2];
console.log(" ~ Automatic Command Input Mode");
//Load the list of commands to be executed in order
const fs = require('fs');
fs.readFile(process.argv[2], "utf8", (err, data) => {
if(err){console.log("[!] Error Loading Command List File :\n",err);}else{
var CMDList = data.split("\n"); // split the document into lines
CMDList.length = CMDList.length - 1; //fix the last empty line
_.each(CMDList, function(this_command, i){
ssh.exec(this_command, {
out: function(stdout) {
console.log("[+] executing command",i,"/",CMDList.length,"\n $["+this_command+"]","\n"+stdout);
}
});
});
console.log("[i]",CMDList.length,"commands will be performed.\n");
ssh.start();
}
});
}
//:Error Handling:
ssh.on('error', function(err) {
console.log('[!] Error :',err);
ssh.end();
});
InitTool();
It uses underscore for looping through the command list.

Categories