error 403 on nodejs when running .js file - javascript

help pls, I am trying to do a POST on my api but I am getting error 403, I read many topics but still not resolved my problem.
I am running my js file on nodejs prompt using comand: node myfilename.js to compile and getting this error. below is my code. I was supposed to get a json file back from the site I am trying to consume.
var app = require('./config/customs-express')();
var unirest = require('unirest');
var crypto = require('crypto');
var qs = require('querystring');
app.listen(3000, function() {
console.log('Server running door 3000');
});
var MB_TAPI_ID = 'xxx';
var REQUEST_HOST = 'https://www.xxxx.net';
var REQUEST_PATH = '/tapi/v3';
var MB_TAPI_SECRET = 'xxx';
var tapi_nonce = Math.round(new Date().getTime() / 1000);
var tapi_method = 'list_orders';
var params = (tapi_method, tapi_nonce);
var params_string = ((REQUEST_PATH) + '?' + (params));
var tapi_mac = crypto.createHmac('sha512', MB_TAPI_SECRET)
.update(tapi_method + ':' + MB_TAPI_SECRET + ':' +
tapi_nonce)
.digest('hex');
unirest.post(REQUEST_HOST)
.headers({'Content-type': 'application/x-www-form-urlencoded'})
.headers({'Key': MB_TAPI_ID})
.headers({'Sign': tapi_mac})
.send(qs.stringify({'method': tapi_method, 'tonce': tapi_nonce}))
.send(qs.stringify(params_string))
.end(function (response) {
console.log(response.body);
});
var app = require('./config/customs-express')();
var unirest = require('unirest');
var crypto = require('crypto');
var qs = require('querystring');
app.listen(3000, function() {
console.log('Server running door 3000');
});

403 means forbidden. The API is telling you "no."
If this works when you visit the page, it probably means they are using cookies. If that is the case, first hit the login page, get a cookie, then send the login request with the cookie. Superagent can do this, for example.

Related

Cannot connect or emit to Amazon ECS Socket.io Server via Socket.io from a HTML file located in S3 bucket

I am having trouble connecting and emitting to an ECS Fargate Socket.io Server on AWS via Socket.io from a HTML file located in a S3 bucket in the same AWS region.
The ECS Fargate Server's code is as follows:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var AWS = require ('aws-sdk');
io.on('connect', function (socket){
console.log('connection made');
socket.on('disconnect', function (socketds) {
console.log("***********************************************");
console.log("Disconnected");
});
socket.on('reconnect', function (socketds) {
console.log("***********************************************");
console.log("Reconnected");
});
socket.on('c_status', function () {
console.log("*********************************************");
console.log("cstatus");
});
socket.on('app_message', function (mdata) {
console.log("***********************************************");
console.log("App-message:",mdata);
socket.emit('command1',mdata);
});
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
And the relevant code of the HTML file is as follows:
<script>
const serverLocation = "http://application-load-balancer-dns-link:3000";
const socket = io(serverLocation);
function sendmsg() {
var date = new Date();
date.setHours(date.getHours() + 4);
var datetm = date.toISOString().split('.')[0]+"Z";
var node_id = $('#innode').val();
var clid = "0";
var msg = $('#message').val();
if (node_id.length === 1) {
var unitcode = "0" + "0" + node_id;
}
else if (node_id.length === 2) {
var unitcode = "0" + node_id;
}
else {
var unitcode = node_id;
}
var mdata = datetm+unitcode+msg;
socket.emit('app_message',mdata);
}
</script>
I have been at it for 2 days now and have not been able to figure it out. It just doesn't connect.
Any help is greatly appreciated.
If you need more information, please let me know.
1) Try checking the inbound rules of the security group associated with that instance.
2) Outbound rules should also be configured as its bidirectional (By Default allows all)
3) If they are perfect. Check whether timeout occurs or any other exception.

NodeJS equivalent of C# code for hmac-sha256 authorization

Im trying to convert the C# code found here:
AMX Authorization Header in order to connect to an external API. The C# code works when trying to connect to the external API but when I convert it to a nodeJS solution it doesnt work.
I dont have access to the external C# API so can't update that side but was hoping someone could look at this and see something Im missing or doing wrong:
My nodejs solution:
var request = require('request');
var uuid = require('node-uuid');
var CryptoJS = require('crypto-js');
var URL = "https://urltoexternalAPI.com";
var itemAPPId = "testAPPId";
var APIKey = "testAPIKey";
var requestUri = encodeURIComponent(URL.toLowerCase());
var requestHttpMethod = "GET";
var requestTimeStamp = Math.floor(new Date().getTime() / 1000).toString();
var nonce = uuid.v1().replace(/-/g, '');
//I excluded the content hashing part as the API Im hitting is a GET request with no body content
var signatureRawData = itemAPPId + requestHttpMethod + requestUri + requestTimeStamp + nonce;
var secretKeyByteArray = CryptoJS.enc.Base64.parse(APIKey);
var signature = CryptoJS.enc.Utf8.parse(signatureRawData);
var signatureBytes = CryptoJS.HmacSHA256(signature, secretKeyByteArray);
var requestSignatureBase64String = signatureBytes.toString(CryptoJS.enc.Base64);
request({
url: URL,
headers: {
'Authorization': "amx "+itemAPPId+":"+requestSignatureBase64String+":"+nonce+":"+requestTimeStamp
}
}, function (error, response, body) {
if (response.statusCode != 200) {
console.log("Fail");
} else {
console.log("Success");
}
});
I figured it out! If anyone ever comes across this issue they may find the below helpful:
the following C# code works a little different to nodeJS:
System.Web.HttpUtility.UrlEncode(request.RequestUri.AbsoluteUri.ToLower());
Initially I copied this functionality as is and wrote the nodejs equivalent as such:
var requestUri = encodeURIComponent(URL.toLowerCase());
The encoding of the URL in C# keeps everything in lowercase - for e.g: https:// becomes https%3a%2f%2f - whereas nodeJS uppercases its encoding characters - https%3A%2F%2F - this is what as causing the incorrect hashing.
The solution is to just move the lowercase function to after the encoding has been done on the URL. Like so:
var requestUri = encodeURIComponent(URL).toLowerCase();
Seems rather simple but when trying to replicate the C# solution you may not pick up that the two URL encoders work differently.
Final solution: (updated to crypto thanks to Yoryo)
const fetch = require("node-fetch");
const uuid = require("uuid");
const crypto = require('crypto');
var URL = "https://urltoapi.com";
var itemAPPId = config.itemAPPId;
var APIKey = config.itemAPIKey;
var requestUri = encodeURIComponent(URL).toLowerCase();
var requestHttpMethod = "GET"; //should be dynamic
var requestTimeStamp = Math.floor(new Date().getTime() / 1000).toString();
var nonce = uuid.v1().replace(/-/g, '');
var signatureRawData = itemAPPId + requestHttpMethod + requestUri + requestTimeStamp + nonce;
var key = Buffer.from(APIKey, 'base64');
var requestSignatureBase64String = crypto.createHmac('sha256', key).update(signatureRawData, 'utf8').digest('base64');
const hitExternalAPI = async url => {
try {
const res = await fetch(url, { method: 'GET', headers: { "Authorization": "amx "+itemAPPId+":"+requestSignatureBase64String+":"+nonce+":"+requestTimeStamp } })
.then(res => {
console.log(res.ok);
});
} catch (error) {
console.log("Error",error);
}
};
hitExternalAPI(URL);

CryptoJs is not decrypting URL on my NodeJS server

I am forwarding API calls from my frontend to my backend. I encrypt the API calls using CryptoJS.AES using the passphrase 'somekey'.
My relevant client code is...
var host = 'http://localhost:3000'
$('.send-button').click(function(){
var request = $('.request-input').val();
var encryptedRequest = CryptoJS.AES.encrypt(request, 'somekey');
console.log(encryptedRequest.toString())
var decryptedRequest = CryptoJS.AES.decrypt(encryptedRequest, 'somekey');
console.log('Decrypted Request: ' + decryptedRequest.toString());
handleRequest(encryptedRequest.toString());
});
var handleRequest = function(request){
$.ajax({
type: "GET",
url: host + '/requests?call=' + request,
success: function(data) {
var rawJSON = JSON.stringify(data, null, 2);
editor.setValue(rawJSON);
},
dataType: 'json'
});
}
relevant server side code is...
var port = 3000;
var serverUrl = "127.0.0.1";
var http = require("http");
var path = require("path");
var fs = require("fs");
var express = require("express");
var CryptoJs = require("crypto-js");
var app = express();
app.get('/requests', function(req, res) {
console.log('REQUEST: ' + req);
var call = req.query.call;
console.log(call)
console.log("To send: " + CryptoJs.AES.decrypt(call, 'somekey'));
});
The problem I keep getting is that it that when I decrypt it it either doesn't get the original URL and instead returns a bunch of jibberish. An example of this is...
Encryption: U2FsdGVkX1/NRbZkyP60pPu3Cb9IcQ4b9n4zJkExp2LNR3O1EdEpqHLNACnYuatN
Decryption: 68747470733a2f2f6e6577736170692e6f72672f76312f61727469636c6573
OR... It just returns nothing and appears blank.
Ideally I would like something like this.
Encryption: U2FsdGVkX1/NRbZkyP60pPu3Cb9IcQ4b9n4zJkExp2LNR3O1EdEpqHLNACnYuatN
Decryption: https://newsapi.org/v1/articles
Can anyone see what I am dong wrong?
Here is a working jsfiddle:
https://jsfiddle.net/5Lr6z4zp/1/
The encryption results in a Base64 string, while the decrypted string is Hex. To get back the “Message” you need to convert that to Utf8: decryptedRequest.toString(CryptoJS.enc.Utf8)
Here is the relevant part of the code that works:
var request = "testing decryption";
var encryptedRequest = CryptoJS.AES.encrypt(request, 'somekey');
console.log(encryptedRequest)
var decryptedRequest = CryptoJS.AES.decrypt(encryptedRequest, 'somekey');
var decryptedMessage = decryptedRequest.toString(CryptoJS.enc.Utf8)
console.log('Decrypted Request: ' + decryptedMessage);
Here is a link for a resources that explains the encryption/decryption in more detail:
http://www.davidebarranca.com/2012/10/crypto-js-tutorial-cryptography-for-dummies/

node.js How to communicate between modules

I'm fairly new to node.js and recently started to make some modules. However I've come to a point where communication between modules is required. Since this is not a problem I've encountered in the past I'm stuck with finding a clean solution.
This is the boilerplate I currently got (Left out some checks to make the code a bit smaller). The basic idea atm is joining any irc channel given by an http post.
bot.js
//Include services
var Webservice = require('./Webservice');
var Ircservice = require('./Ircservice');
//Create service instances
var webservice = new Webservice();
var ircservice = new Ircservice();
//Initialize services
webservice.init(1337);
ircservice.init('alt-irc.snoonet.org', 80, 'User');
//Handle events
ircservice.on('irc-registered', function(msg){
console.log(ircservice.connected);
ircservice.joinChannel('#testchannel')
});
ircservice.on('irc-join', function(channel){
console.log('Successfuly joined: ' + channel);
});
webservice.on('web-join', function(streamer){
ircservice.joinChannel('#' + streamer);
});
Webservice.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
app.use(bodyParser.urlencoded({
extended: true
}));
var Webservice = function(){
EventEmitter.call(this);
};
Webservice.prototype.init = function(port){
app.listen(port, function () {
console.log('Webserver listening on ' + port);
});
this.initRoutes();
};
Webservice.prototype.initRoutes = function(){
var self = this;
//join a irc-channel
app.post('/join', function (req, res) {
var streamer = req.body.name;
self.emit('web-join', streamer);
res.send('Received')
});
};
util.inherits(Webservice, EventEmitter);
module.exports = Webservice;
Ircservice.js
var irc = require('irc');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var Ircservice = function(){
EventEmitter.call(this);
}
Ircservice.prototype.init = function(server, port, nick){
this.client = new irc.Client(server, nick, {
port: parseInt(port)
});
this.initListerners();
};
Ircservice.prototype.initListerners = function(){
var self = this;
this.client.addListener('message', function (from, to, message) {
console.log(from + ' => ' + to + ': ' + message);
});
this.client.addListener('join', function(channel, nick, message){
self.emit('irc-join', channel);
});
};
Ircservice.prototype.joinChannel = function(channel){
this.client.join(channel, null);
};
util.inherits(Ircservice, EventEmitter);
module.exports = Ircservice;
This example works perfectly, but as you can see the communication between my webservice and ircservice is handled by the bot.js. While this is perfectly fine for this example, I cannot use this method whenever I want.
Let say in the future I want to keep a list in my ircservice of all channels he has joined and display this through a webpage. I could keep a local array on my ircservice and on the join event add that channel to the array. But how do I continue on the webservice end. I can write an endpoint '/getchannels' but my webservice itself is not aware of the ircserver to get the channels (ircservice.getChannels or something similar) and firing an event in my web request doesn't feel like the way to go.
One solution that came up in my mind was passing the instances of the services to each other like webservice.setIrcservice(ircservice) and the other way around in the bot.js. But this feels like dirty code and a hard depency.
So how can I communicate between modules when I need data instantaneously and events are no option?

send PDF file using websocket node.js

I have the following server:
var pvsio = require("./pvsprocess"),
ws = require("ws"),
util = require("util"),
http = require("http"),
fs = require("fs"),
express = require("express"),
webserver = express(),
procWrapper = require("./processwrapper"),
uploadDir = "/public/uploads",
host = "0.0.0.0",
port = 8082,
workspace = __dirname + "/public",
pvsioProcessMap = {},//each client should get his own process
httpServer = http.createServer(webserver),
baseProjectDir = __dirname + "/public/projects/",
PDFDocument = require ("pdfkit");
var p, clientid = 0, WebSocketServer = ws.Server;
...
var wsServer = new WebSocketServer({server: httpServer});
wsServer.on("connection", function (socket) {
var socketid = clientid++;
var functionMaps = createClientFunctionMaps();
socket.on("message", function (m) {
Is possible send a pdf file to the client inside socket.on("message" .. function ?
I can send message using send(), there is some function to send files?
Thanks
I would just send the pdf in binary.
fs.readFile(something.pdf,function(err,data){
if(err){console.log(err)}
ws.send(data,{binary:true});
}
And at the client side, I would create a blob and an object url from the received binary data. From this onward, you can pretty much do anything, says open the pdf file in a new window/tab.
conn.onmessage = function(e){
pdfBlob = new Blob([e.data],{type:"application/pdf"});
url = webkitURL.createObjectURL(pdfBlob);
window.open(url);
}
Hope this help.

Categories

Resources