I have written a shell script code which is successfully adding a new OS Connection IP in Imperva system/instance.
## Create a new IP OS connection in a given site, server group.
create_ip()
{
JSESSIONID="${1}"
addThisIP="${2}"
siteName="${3}"
serverGroupName="${4}"
echo -e "\n- Trying to create a new OS connection IP now.\n";
##Make sure while initiating a REST API call, any parameter which has ' ' (space) in Imperva should be substituted with '%20'.
##JSESSIONID will be generated first and will be available to this function
create_new_ip_output="$(curl -ik -X POST -H "Cookie: JSESSIONID=$JSESSIONID" -H "Content-Type: application/json" -H "Accept: application/json" "https://${MX}:8083/SecureSphere/api/v1/conf/serverGroups/${siteName// /%20}/${serverGroupName// /%20}/servers/${addThisIP}" -d '{"connection-mode":"SSH","host-name":"thisLinuxServer.fdqn","OS-type":"linux","user-name":"enter_your_userID"}')";
return_code="$?";
if [[ "${return_code}" == "0" && ! `echo "${create_new_ip_output}" | grep "do not have permission"` ]]; then
echo -e "\n\n- OS connection IP (${addThisIP}) created successfully in site: ${siteName}, servergroup: ${serverGroupName} and stdout:\n${create_new_ip_output}\n";
return 0;
else
echo -e "\n\n- Failed to create a new OS connection IP (${addThisIP}) in site: ${siteName} and servergroup: ${serverGroupName}\n- using session ID: ${JSESSIONID}, error log:\n${create_new_ip_output}\n";
return 1;
fi
}
OK, the above code works fine and once run, I see valid output showing whether an IP got added successfully or what was the failure message.
Now, I'm trying to implement the same functionality in NodeJS.
To do that, I have successfully created functions to generate JSESSIONID (so that I can use it to perform multiple REST/API call operations, rather than creating a new session each time for any operation), successfully deleting a JSESSIONID (i.e. to logoff/out from Imperva session so that I don't hit the limit) and to successfully search an IP in Imperva system if it has been previously added.
Using the above shell script logic, I have written the following NodeJS code to add a new OS Connection IP in Imperva using Rest/API, but I'm getting an error.
//Imperva create IP
//qData is a hash array that has valid index/value pair values.
var impervaCreateIP = function(qData){
var deferred = Q.defer();
var data = ''
var options = {
hostname: 'myImpervaServerInstance.mycompanydomain.com',
port: 8083,
method: 'POST',
path: '/SecureSphere/api/v1/conf/serverGroups/'+ qData['siteName'] + '/' + qData['serverGroupName'] + '/servers/' + qData['ip'],
headers: {
'Content-Type': 'application/xml',
'X-Requested-With': 'Nodejs',
'Cookie': 'JSESSIONID='+qData['sid']
}
}
//svtLog() is a logger that I'm using to log messages to a file. Out of scope of this post.
svtLog('info','Imperva','Inside impervaCreateIP function')
svtLog('info','Imperva',qData['ip'])
svtLog('info','Imperva',qData['siteName'])
svtLog('info','Imperva',qData['serverGroupName'])
svtLog('info','Imperva','')
console.log('Inside impervaCreateIP')
console.log(options);
httpHelp(options, data)
.then(function(fullResponse){
var result = JSON.parse(fullResponse[1])
console.log("11 -----")
console.log(result)
console.log("22 -----")
deferred.resolve(qData['sid'])
console.log(result)
})
.fail(function(e){
svtLog('error','Imperva','Failed to add IP in Imperva')
svtLog('info','Imperva',qData['ip'])
svtLog('error','Imperva',e)
svtLog('info','Imperva','')
deferred.reject(e)
})
return deferred.promise;
}
Error message:
Inside impervaCreateIP
{ hostname: 'myImpervaServerInstance.mycompanydomain.com',
port: 8083,
method: 'POST',
path: '/SecureSphere/api/v1/conf/serverGroups/some%20Site%20NameInImperva/someServerGroupNameInImperva_01/servers/10.20.30.40',
headers:
{ 'Content-Type': 'application/xml',
'X-Requested-With': 'Nodejs',
Cookie: 'JSESSIONID=7B3C378D365B673F6C749847DEDC7D8F } }
[SyntaxError: Unexpected token <]
I'm looking for 2 things:
1. How to resolve the error (as shown above).
2. How to pass CURL's -d option {...} body parameters in the NodeJS code above, like I used it in the shell script.
PS: Changing POST to GET (method), assures that the code is fine syntax wise as it successfully shows the IP (with GET operation) with the above NodeJS code.
So, it's failing only when I use POST (i.e. when I'm trying to create an IP) -vs- GET (which I use to find an IP exist or not). I checked as per the Imperva API doc, the response comes in JSON format. Not sure if due to missing bullet# 2 question, I'm getting this Syntax error with POST.
OK.
Solution to both bullet# 1 and #2 was to set the CURL "-d option values" in NodeJS like shown below (I was setting it blank earlier):
var data = '{"connection-mode":"SSH","host-name":"thisLinuxServer.fdqn","OS-type":"linux","user-name":"enter_your_userID"}'
Now, both options and data will be sent to httpHelp(options,data) and it'll work.
The above is just an dummy data value. Usually I'd pass valid host-name in the JSON object.
Never thought that not setting the data variable would result in this syntax error.
Other thing, I was missing BIG time was the value for 'Content-Type' inside headers variable. That was the reason, the error message was having "<" bracket in it (as by default it looks for a <body>...</body> section containing some XML format but in our case, the HTML response contained or was getting returned in JSON { ... } format way for the body section. That's why it was showing an error for unexpected token <.
As per the API doc, it should have been "JSON" type, thus changed that line to
'Content-Type': 'application/json',
Related
I'm still new enough with Node that HTTP requests trip me up. I have checked all the answers to similar questions but none seem to address my issue.
I have been dealt a hand in the Wild of having to go after JSON files in an API. I then parse those JSON files to separate them out into rows that populate a SQL database. The API has one JSON file with an ID of 'keys.json' that looks like this:
{
"keys":["5sM5YLnnNMN_1540338527220.json","5sM5YLnnNMN_1540389571029.json","6tN6ZMooONO_1540389269289.json"]
}
Each array element in the keys property holds the value of one of the JSON data files in the API.
I am having problems getting either type of file returned to me, but I figure if I can learn what is wrong with the way I am trying to get 'keys.json', I can leverage that knowledge to get the individual JSON data files represented in the keys array.
I am using the npm modules 'request' and 'request-promise-native' as follows:
const request = require('request');
const rp = require('request-promise-native');
My URL is constructed with the following elements, as follows (I have used the ... to keep my client anonymous, but other than that it is a direct copy:
let baseURL = 'http://localhost:3000/Users/doug5solas/sandbox/.../server/.quizzes/'; // this is the development value only
let keysID = 'keys.json';
Clearly the localhost aspect will have to go away when we deploy but I am just testing now.
Here is my HTTP call:
let options = {
method: 'GET',
uri: baseURL + keysID,
headers: {
'User-Agent': 'Request-Promise'
},
json: true // Automatically parses the JSON string in the response
};
rp(options)
.then(function (res) {
jsonKeysList = res.keys;
console.log('Fetched', jsonKeysList);
})
.catch(function (err) {
// API call failed
let errMessage = err.options.uri + ' ' + err.statusCode + ' Not Found';
console.log(errMessage);
return errMessage;
});
Here is my console output:
http://localhost:3000/Users/doug5solas/sandbox/.../server/.quizzes/keys.json 404 Not Found
It is clear to me that the .catch() clause is being taken and not the .then() clause. But I do not know why that is because the data is there at that spot. I know it is because I placed it there manually.
Thanks to #Kevin B for the tip regarding serving of static files. I revamped the logic using express.static and served the file using that capability and everything worked as expected.
I'm writing a rule in Auth0 to trigger a verification email if a certain condition is met. To make the example small I have included the code which I am using to send the verification mail (I have removed out the unwanted code).
var url = 'https://myname.au.auth0.com/api/v2/jobs/verification-email';
var token = 'Bearer {{token}}'; //This is where the problem is how do I get the token
var userId = user.user_id;
request.post({
url: url,
headers: {
Authorization: 'Bearer {{token}}',
},
json: {
"user_id": user.user_ID
},
timeout: 5000
},
function(err, res, body) {
console.log(err);
console.log(res);
});
In the body I get the following error
{ statusCode: 400,
error: 'Bad Request',
message: 'Bad HTTP authentication header format',
errorCode: 'Bearer' }
I guess I need to pass in the access token or something like that in the header. How do I get this done?
I also saw the following article (https://auth0.com/docs/email/custom), however I'm not sure what secretToken is?
Starting from the bottom, the article (https://auth0.com/docs/email/custom) is aimed at users that want additional flexibility and use their own custom email handling. The secretToken on that example it's just to illustrate a possible - and very simple - way that their own custom email API could validate that they were being called from Auth0; in conclusion it would work almost as an API key.
If you only need to trigger a verification email through the system provided by Auth0 you're using the correct approach (Management API v2). You have more than one way to obtain a token that allows you to call this API:
Using the client credentials grant
Using the Auth0 Management API v2 Explorer
The second option would be the easiest to get started, but do take in consideration that there's a deprecation notice for that one.
Once you obtain the token, you also need to correctly pass it to the API. The code you showed may be only sample code, but make sure that you don't end up including the Bearer scheme twice, more specifically var token = 'Bearer {{token}}'; should instead just be var token = '{{token}}'; and then you would use the token variable when creating the HTTP header.
Just created the below empty rule that will get called when user tries to login and email is not yet verified and it works like a charm :D
function (user, context, callback) {
if (!user.email_verified) {
console.log("User is: " + user.user_id);
var ManagementClient = require('auth0#2.6.0').ManagementClient;
var management = new ManagementClient({
token: auth0.accessToken,
domain: auth0.domain
});
var new_userobj = {user_id:user.user_id};
management.sendEmailVerification(new_userobj,callback(new UnauthorizedError('Please click on the link in the email we have sent you to continue to login.')));
} else {
return callback(null, user, context);
}
}
I received the same error when using the wrong token, though for a different api call. I recreated your issue by using a user's access_token obtained by calling {{api-audience}}users/{{user_id}}. That token should look something like this: A1bCd2efg34IJkl5
Try using a client's access_token obtained by making this call:
curl --request POST \
--url https://{{domain}}/oauth/token \
--header 'content-type: application/json' \
--data '{
"client_id":"{{client_id}}",
"client_secret":"{{client_secret}}",
"audience":"{{audience}}",
"grant_type":"client_credentials"
}'
That token will be a full JWT.
Thanks for so many fast response.
I used NodeJS(v4.3.2) and ExpressJs(v4.x) to build up website.
I used a lot AJAX and all AJAX url point to one static IP(AWS Server itself).
Because I would deploy to several servers, I don't want to change AJAX url separately.
My idea is when I run "node bin/www" command line, Can I change it to "node bin/www 50.50.50.50(my AWS address)" and I can set all AJAX url to the right IP?
Is it possible or other alternative solustion?
Thanks
Your issue is related to CORS : basically, you cannot access a domain http://www.example1.com from http://www.example2.com via Ajax if http://www.example1.com does not explicitly allows it in the response.
This is a "security" feature on most modern browsers. You won't encounter this problem using command line such as curl or chrome extension Postman.
To fix this, make sure the domain requesting the data (http://www.example2.com) is allowed in the Access-Control-Allow-Origin header in your server's response, as well as the http verb (GET, POST, PUT... or * for every http methods).
It all comes down to add the two following headers to the http://www.example1.com server's response :
Access-Control-Allow-Origin: http://www.example2.com
Access-Control-Allow-Methods: *
Edit
Following #Paulpro's comment, you have to rebase all your urls so that they reach your server's IP instead of your localhost server.
I fix this problem.
First, in bin/www
append these code to retrieve URL for command line and store into json file.
function setUpURL(){
var myURL = process.argv[2];
console.log('myURL: ', myURL);
var outputFilename = 'public/myURL.json';
var myData = {
port:myURL
}
fs.writeFile(outputFilename, JSON.stringify(myData, null, 4), function(err) {
if(err) {
console.log(err);
} else {
console.log("JSON saved to " + outputFilename);
}
});
};
Then in each JS containing ajax add these code in the head of JS file (it need to load before ajax)
var myURL;
$.getJSON("myURL.json", function(json) {
myURL = json.port.toString();
console.log(myURL);
});
new ajax format
$.ajax({
type: "POST",
url: myURL + "/forgetPwd",
data: sendData,
success: function(data){
window.location.replace(myURL);
},
error: function(data){
}
});
Finally, you can run server
node bin/www your_aws_ip
It works for me now. Hope these will help you guys.
By the way, you should be careful about the path of myURL.json.
I used Parse's CLI with the new Heroku integration to create the scaffold NodeJS project (parse new).
The example cloud function it gives you is:
// Hello
Parse.Cloud.define('hello', function(request, response) {
response.success('Hello world! ' + (request.params.a + request.params.b));
});
I can hit this route with the following CURL command and everything works fine:
curl -X POST \
-H "X-Parse-Application-Id: b8qPYS4SLSz0WoSWXlWeQosmF2jJPUPydetg3esR" \
-H "X-Parse-REST-API-Key: TOJLbfbNXSQcBdDVnU0MnKVu7SyamQvZmorHL5iD" \
-H "Content-Type: application/json" \
-d '{"a": "Adventurous ", "b": "Parser"}' \
https://api.parse.com/1/functions/hello
But then I added a new Class to my Parse Data, inserted a row, and tried to query & return the results. I keep getting {"code":143,"error":"Invalid webhook response status: 500 Internal Server Error"} as the response.
I'm fairly certain it is not my code that is the problem and am guessing there is some configuration step or something I'm missing.
Here is my modified Parse function:
// Hello
Parse.Cloud.define('hello', function(request, response) {
var query = Parse.Query("Favorites");
query.find({ useMasterKey: true }).then(
function(results) {
response.success('win');
}, function() {
response.error('fail');
});
});
And a picture of my Parse Class with the inserted row:
I have Googled the error and can't find any good answers only poorly worded questions. I'm completely at a loss here. Thanks in advance for your help.
Looks like Parse is wrong initialised on register-webhooks.js post deploy script:
Parse.initialize(process.env.PARSE_APP_ID, "unused", process.env.PARSE_MASTER_KEY);
And without second parameter (JavaScript Key) you can't execute any Parse.Query from cloud functions.
So my solution is:
Add new PARSE_JS_KEY to Heroku Config Variables (value is JavaScript Key from Parse->Settings->Keys)
In server.js file add line:
Parse.initialize(process.env.PARSE_APP_ID, process.env.PARSE_JS_KEY, process.env.PARSE_MASTER_KEY);
before require('./cloud/main.js');
PS: Place process.env.PARSE_JS_KEY directly in register-webhooks.js initializer does not work.
I have been trying to make this post request to the github api for the last couple of days, but unfortunately the response is coming back as "bad message"
here is the piece of code we are sending in the post request using https request in node -
This is the post data
var issueData = JSON.stringify({
"title":title,
"body":comment
});
This is the options file
var options = {
host: 'api.github.com',
path: '/repos/sohilpandya/katasohil/issues?access_token='+sessions.token,
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0',
},
method: 'POST'
};
This is the https request
var requestaddIssue = https.request(options, function(responseFromIssues){
responseFromIssues.setEncoding('utf8');
responseFromIssues.on('data', function(chunk){
console.log('>>>>chunk>>>>>',chunk);
issueBody += chunk;
});
responseFromIssues.on('end',function(issueBody){
console.log(issueBody);
});
});
requestaddIssue.write(issueData);
requestaddIssue.end();
I have tried another approach where the authentication token for the user is in the header as
'Authentication': 'OAuth '+ sessions.token (where we are storing token inside sessions)
But the chunk response always seems to come back with the following in the console log.
{
"message": "Not Found",
"documentation_url": "https://developer.github.com/v3/issues/#create-an-issue"
}
I have tried the same in apigee and it seems to work ok and returns to correct response. Hoping someone can find the minor error in the code above that is causing this bad message error.
Except the issueBody variable is not defined in the snippets you posted, the code is correct. I tried it using a personal access token.
The error you get appears because you need to add a scope with power to open issues.
I tried the repo and public_repo scopes and they are both working. Note that repo has access to private repositories. Here you can see the list of scopes.
If you're using OAuth, then you you should have an url looking like this:
https://github.com/login/oauth/authorize?client_id=<client-id>&scope=public_repo&redirect_uri=<redirect-uri>