Javascript - accessing password in ssh2 connection - javascript

I have a class which is being used to connect to a device. I have made in instance of the class in my application
app.js
myConn = new myConnection();
myConnection.js
function myConnection(){
this.settings = {
host: '192.168.225.195',
port: 22,
username: 'sysadmin',
password: 'pass'
};
}
I have a function within said class that executes a command on the remote device but that requires a password. When this happens stderr.on is executued and I send the password and a newline char.
myConnection.prototype.installPatch = function(callback){
this.conn.exec('sudo -S bash /tmp/update.sh', function(err, stream){
var standardMsgs = '';
var errorMsgs = '';
if(err) throw err;
stream.on('close', function(code, signal) {
callback(standardMsgs, errorMsgs);
}).on('data', function(data) {
standardMsgs += "<br>" + data;
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
errorMsgs += data;
console.log('STDERR: ' + data);
stream.write(myConn.conn.config.password + '\n');
});
});
}
While this works I am not a fan of accessing the password with
stream.write(myConn.conn.config.password + '\n');
since a change to the name "myConn" in app.js would required the same change in the "installPatch" function.
I had intended to use
stream.write(this.settings.password + '\n');
Do I have any other options that will allow me to retrieve the password from within the myConnection class? I hope I am just overlooking the obvious.

Ok, so I believe it was starring me in the face.
Change
stream.write(myConn.conn.config.password + '\n');
to
stream.write(stream._client.config.password + '\n');

Related

NodeJS - Run seperate functions depending on OS (Closed)

How do we run seperate functions based on the users Operating System?
I have two functions for returning relative paths to given files by searching for them recursively within subdirectories of given working directory's.
I have one for Windows, see below..
WINDOWS variant
console.log("Locating File...");
exec('set-location ' + folder + ';' + ' gci -path ' + folder + ' -recurse -filter ' +
file + ' -file | resolve-path -relative', { 'shell':'powershell.exe' }, (error, stdout, stderr) => {
var filePath = stdout.substring(stdout.indexOf(".\\") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate the file...");
return;
}
And one for Linux & macOS, see below...
LINUX/OSX variant
console.log("Locating File...")
console.log();
exec('find -name "' + file + '"', { cwd: folder }, (error, stdout, stderr) => {
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate the file...");
return;
}
I want to execute these functions based on the users Operating System if that's possible?
I've had a look at the StackOverflow question..
How do I determine the current operating system with Node.js
which is how I found out how to detect the current user OS, as well as the StackOverflow Question..
python: use different function depending on os.
Aside from the 2nd issue referenced being for python, I am basically trying to achieve the same thing from the 2nd issue but with nodeJS, by using the solution from the 1st issue.
My latest attempt was the following below, but for some reason it doesn't return anything but a blank console.
const fs = require("fs");
const platform = require("process");
const path = require("path");
var exec = require("child_process").exec
var folder = "just/some/folder/location"
var file = "file.txt"
// Windows process
if (platform === "win32") {
console.log("Locating File...");
exec('set-location ' + folder + ';' + ' gci -path ' + folder + ' -recurse -filter ' +
file + ' -file | resolve-path -relative', { 'shell':'powershell.exe' }, (error, stdout, stderr) => {
// relative path output for Windows
var filePath = stdout.substring(stdout.indexOf(".\\") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate the file...");
return;
} else if (process.platform === "linux" + "darwin") {
// Linux & Unix process
console.log("Locating File...")
console.log();
exec('find -name "' + file + '"', { cwd: folder }, (error, stdout, stderr) => {
// relative path output for Linux & macOS
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate file... \n\n" + error);
return;
};
console.log("found file: " + filePath);
// Read the file and show it's output to confirm everything ran correctly.
fs.readFile(path.join(folder, file), (error, data) => {
if (error) {
console.log("error reading file \n\n" + error);
return;
}
});
});
};
});
};
Problem solved, after doing a bit of research, I was using if else else if statements & process.platform wrong...
First, when I was declaring process.platform I was using...
const platform = require("process");
when according to process.platform documentation for CJS it should be...
const { platform } = require("node:process");
Second, I was using if else else if statements wrong!
In my issue stated above I was using if else else if statements with process.platform like so..
} else if (process.platform === "linux" || "darwin") {
// Linux & macOS code to execute
}
which was completely wrong!
I should have been using if else else if statements with process.platform like so...
if (process.platform === "win32") {
// Windows code to be executed!
} else if (process.platform === "linux") {
// Linux Code to be executed!
} else {
process.platform === "darwin";
// macOS Code to be executed!
}
I've managed to produce the following code which works on Windows, Linux and macOS closest to the way I need it to.
Hopefully this helps anyone new to JS like me.
const fs = require("fs");
const { platform } = require("node:process");
const path = require("path");
var exec = require("child_process").exec
var folder = "just/some/folder/location"
var file = "file.txt"
// Windows Process
if (process.platform === "win32") {
// executes Powershell's "set-location" & "gci" commands...
//...to locate a given file recursively...
//...and returns its relative path from inside the given...
//...working directory's subdirectories.
exec('set-location "' + '"' + folder + '"'
+ ';' + ' gci -path ' + '"' + folder + '"'
+ ' -recurse -filter ' + '"' + file + '"' +
' -file | resolve-path -relative', (error, stderr, stdout) => {
// sets the relative file path from ".\this\way\to\the\file.txt",
// to "this\way\to\the\file.txt".
var filePath = stdout.substring(stdout.indexOf(".\\") + 2).trim("\n");
// throw an error if the file isnt found at all!
if (error !== null) {
console.log("Cannot locate the given file... \n" + error);
return;
};
// read the file after it's been found.
fs.readFile(path.join(folder, filePath), 'utf8', (error, data) => {
if (error) {
console.log("There was a problem reading the given file... \n" + error);
return;
};
// Then print the data from fs.readFile...
//...to confirm everthing ran correctly.
console.log(data);
});
});
} else if (process.platform === "linux") {
// executes findUtil's "find" command...
//...to locate a given file recursively...
//...and return its relative path from inside the given...
//...working directory's subdirectories.
exec('find -name "' + file + '"', { cwd: folder }, (error, stderr, stdout) => {
// sets the relative file path from "./this/way/to/the/file.txt",
// to "this/way/to/the/file.txt".
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
// throw an error if the file isnt found at all!
if (error !== null) {
console.log("Cannot locate the given file... \n" + error);
return;
};
// read the file after it's been found.
fs.readFile(path.join(folder, filePath), 'utf8', (error, data) => {
if (error) {
console.log("There was a problem reading the given file... \n" + error);
return;
};
// Then print the data from fs.readFile...
//...to confirm everthing ran correctly.
console.log(data);
});
});
} else {
// Uses APPLES built BSD findUtils 'find' command to locate the file inside the folder and subdirectories
exec('find ' + '"' + apkFolder + '"' + ' -name ' + '"' + file + '"', (error, stderr, stdout) => {
// sets the relative file path from "./this/way/to/the/file.txt",
// to "this/way/to/the/file.txt".
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
// throw an error if the file isnt found at all!
if (error !== null) {
console.log("Cannot locate the given file... \n" + error);
return;
};
// read the file after it's been found.
fs.readFile(path.join(folder, filePath), 'utf8', (error, data) => {
if (error) {
console.log("There was a problem reading the given file... \n" + error);
return;
};
// Then print the data from fs.readFile...
//...to confirm everthing ran correctly.
console.log(data);
});
});
}

How to post mentions to slack incoming webhooks

The mentions I send to the incoming webhook renders as plain text.
Note: Sending post request using the request package.
Tried the following:
sending mentions as <#userid>
Result: <#userid> // as plain text
request.post(
`${channels[message.channel.name]}`,
{
json: {
text:
'To: ' + mapDiscordToSlackNames(message.mentions.users) + '\n' +
'Discord channel: #' + message.channel.name + '\n' +
'Link: <' + message.url + '|Link to post>' + '\n' +
Result: To: #soda // as plain text not as mention to #soda user
Entire Code
// require the discord.js module
const Discord = require('discord.js');
const devs = require('./devs.json');
const channels = require('./channels.json');
const dotenv = require('dotenv');
const path = require('path');
var request = require('request');
dotenv.load({
path: path.join(__dirname, `.env`),
silent: true
});
// create a new Discord client
const client = new Discord.Client();
// Map discord usernames of devs to slack usernames
function mapDiscordToSlackNames(discordUsers) {
return discordUsers.map( user => {
return '#' + devs[user.username];
})
}
// when the client is ready, run this code
// this event will only trigger one time after logging in
client.once('ready', () => {
console.log('Discord Connected!');
});
// on message on discord
client.on('message', message => {
console.log(channels[message.channel.name]);
request.post(
`${channels[message.channel.name]}`,
{
json: {
text:
'To: ' + mapDiscordToSlackNames(message.mentions.users) + '\n' +
'Discord channel: #' + message.channel.name + '\n' +
'Link: <' + message.url + '|Link to post>' + '\n' +
'Original Message: \n' +
'\t"' + message.author.username + ': ' + message.cleanContent + '"\n' +
`Attachements: ${message.attachments.map(attachment => attachment.url)}`
},
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
);
});
// login to Discord with app's token
client.login(process.env.DISCORD_TOKEN);
devs is a json object which has returns slack usernames corresponding to discord usernames.
Turns out I was sending userid by escaping '<' & '>' in string like
'&lt#userid&gt' and so it was passing as plain text.
To mention someone in slack do 'To: <#' + userid + '>'
The userid starts with U and can be found after the team/ in url of
your workspace eg: Cxxxxx/team/Uxxxxx/

Parsing Unexpected End

Can someone please explain me why I am getting an issue with this one line because for some reason when I run it with node in the console I'm receiving the Unexpected end of input at Object.parse(native) response.
var profile = JSON.parse(body);
Full code:
//Problem: We need a simple way to look at a user's badge count and Javascript points
//Solution: Use Node.js to connect to Treehouse's API to get profile information to print out
var http = require("http");
var username = "testuser";
//Print out message
function printMessage(username, badgeCount, points) {
var message = username + " has " + badgeCount + " total badge(s) and " + points + " points in Javascript";
console.log(message);
}
//Print out error messages
function printError(error) {
console.error(error.message);
}
//Connect to API URL (http://teamtreehouse.com/username.json)
var request = http.get("http://teamtreehouse.com/" + username + ".json", function(response) {
var body = "";
//Read the data
response.on('data', function(chunk) {
body += chunk;
});
response.on('end', function() {
if(response.statusCode == 200){
try {
var profile = JSON.parse(body);
printMessage(username, profile.badges.length, profile.points.Javascript);
} catch(error) {
//Parse Error
printError(error);
}
} else {
//Status Code Error
printError({message: "There was an error getting the profile for " + username +". (" + http.SSTATUS_CODES[response.statusCode] + ")"});
}
});
//Parse the data
//Print the data
});
//Connection Error
request.on('error', printError);
When I try to browse to http://teamtreehouse.com/test.json, it redirects me to the corresponding HTTPS url. Use the nodejs https module and use the https version of the url : https://teamtreehouse.com/test.json.
Or use the popular request module that can handle redirects and https : https://github.com/request/request. It is easier to use as well.

Uploaded images are not saving in targeted path in Node.js

I am just trying to upload and save images in my public/images folder, I am getting the details of file by req.files, after that I am getting this type of Error: EXDEV, rename 'c:\Users\abdul\AppData\Local\Temp\3348-qiy7kl.jpg'
here is my stuff
app.post('/upload',function(req,res){
var tmp_path = req.files.file.path;
var target_path = './public/images/' + req.files.file.originalFilename;
fs.rename(tmp_path, target_path, function(err) {
if (err) throw err;
fs.unlink(tmp_path, function() {
if (err) throw err;
res.send('File uploaded to: ' + target_path + ' - ' + req.files.file.size + ' bytes');
});
});
})
};
Can any body give any suggestion or give me any reference so that I can handle it?
Try this one
console.log("File Name " + req.files.file.name);
console.log("File Path " + req.files.file.path);
fs.readFile(req.files.file.path, function (err, data) {
var newPath = "public/images/" + req.files.file.originalFilename;
console.log(newPath);
/// write file to uploads/fullsize folder
fs.writeFile(newPath, data, function (err) {
/// let's see it
});

Node.js net library: getting complete data from 'data' event

I've searched around, and either can't find the exact question I'm trying to answer, or I need someone to explain it to me like I'm 5.
Basically, I have a Node.js script using the Net library. I'm connecting to multiple hosts, and sending commands, and listening for return data.
var net = require('net');
var nodes = [
'HOST1,192.168.179.8',
'HOST2,192.168.179.9',
'HOST3,192.168.179.10',
'HOST4,192.168.179.11'
];
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
conn.on('connect', function() {
conn.write (login_string); // login string hidden in pretend variable
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else if (read.match(/Command OK/)) { // command_string returned successful,
// read until /\r\nEND\r\n/
// First part of data comes in here
console.log("Got a response from " + ip + ':' + read);
}
else {
//rest of data comes in here
console.log("Atonomous message from " + ip + ':' + read);
}
});
conn.on('end', function() {
console.log("Lost conncection to " + ip + "!!");
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}
nodes.forEach(function(node) {
var nodeinfo = node.split(",");
connectToServer(nodeinfo[0], nodeinfo[1]);
});
The data ends up being split into two chunks. Even if I store the data in a hash and append the first part to the remainder when I read the /\r\nEND\r\n/ delimiter, there's a chunk missing out of the middle. How do I properly buffer the data in order to make sure I get the complete message from the stream?
EDIT: Ok, this seems to be working better:
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string);
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else {
completeData += read;
}
if (completeData.match(/Command OK/)) {
if (completeData.match(/\r\nEND\r\n/)) {
console.log("Response: " + completeData);
}
}
});
conn.on('end', function() {
console.log("Connection closed to " + ip );
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}
My biggest problem was apparently a logic error. I was either waiting for the chunk that began the reply, or the chunk that ended it. I wasn't saving everything in-between.
I guess if I wanted to get all Node-ish about it, I should fire an event whenever a complete message came in (beginning with a blank line, ending with 'END' on a line by itself), and do the processing there.
You shouldn't do anything with the data you recieve, until you receive the end event. The end callback means that all data chunks have been sent through the stream to your callbacks. If data comes in more than one chunk, you need to create a variable within your function closure to store this data to. Most programs can work just fine ignoring this fact, because data usually comes across in one chunk. But sometimes it doesn't. It doesn't even necessarily depend on the amount of data. If you're in a situation where this is happening, I created an example that demos how to handle it. I basically used your code, but removed all the fluff... this is just demoing the logic you need to collect all the data and do work on it.
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string); // login string hidden in pretend variable
});
conn.on('data', function(data) {
completeData += data;
var dataArray = completeData.split('your delimiter');
if(dataArray.size > 1) { //If our data was split into several pieces, we have a complete chunk saved in the 0th position in the array
doWorkOnTheFirstHalfOfData(dataArray[0]);
completeData = dataArray[1];// The second portion of data may yet be incomplete, thise may need to be more complete logic if you can get more than one delimeter at a time...
}
});
conn.on('end', function() {
//do stuff with the "completeData" variable in here.
});
}
My problem was a logic problem. I was either looking for the chunk that began the message, or the chunk that ended the message, and ignoring everything in between. I guess expected the entirety of the reply to come in in one or two chunks.
Here's the working code, pasted from above. There's probably a more Node-ish way of doing it (I should really emit an event for each chunk of information), but I'll mark this as the answer unless someone posts a better version by this time tomorrow.
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string);
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else {
completeData += read;
}
if (completeData.match(/Command OK/)) {
if (completeData.match(/\r\nEND\r\n/)) {
console.log("Response: " + completeData);
}
}
});
conn.on('end', function() {
console.log("Connection closed to " + ip );
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}

Categories

Resources