Can someone help me convert this Curl request into node.js? - node.js

I'm working with Webhooks and I am trying to run a Curl request from my node.js code. I'm using the npm request package to do this. I'm having trouble finding the proper way to convert the Curl request to code in my application that will send the request.
This is the Curl request:
curl -X POST https://tartan.plaid.com/connect \
-d client_id=test_id \
-d secret=test_secret \
-d username=plaid_test \
-d password=plaid_good \
-d type=wells \
-d options='{
"webhook":"http://requestb.in/",
"login_only":true }'
This works fine when I run it in my terminal so I know the credentials work and it is talking to the server.
Here is my Node.js code:
var request = require('request');
var opt = {
url: 'https://tartan.plaid.com/connect',
data: {
'client_id': 'test_id',
'secret': 'test_secret',
'username': 'plaid_test',
'password': 'plaid_good',
'type': 'wells',
'webhook': 'http://requestb.in/',
'login_only': true
}
};
request(opt, function (error, response, body) {
console.log(body)
});
It should return an item but all I am getting is:
{
"code": 1100,
"message": "client_id missing",
"resolve": "Include your Client ID so we know who you are."
}
All the credentials are from the Plaid website and they work in my terminal just fine so I think it's just the way I am writing my Node.js code that is causing the problem.
If anyone could help my find the right way to write the node code so that it does what the curl request does in the terminal that would be appreciated! Thanks!

You may want to use form: instead of data: in your options. Hopefully that will do the trick.

The default method for request is GET. You want a POST, so you have to set that as a parameter. You also have to send the data as JSON according to the documentation. So I believe this should work:
var opt = {
url: 'https://tartan.plaid.com/connect',
method: "POST",
json: {
'client_id': 'test_id',
'secret': 'test_secret',
'username': 'plaid_test',
'password': 'plaid_good',
'type': 'wells',
'webhook': 'http://requestb.in/',
'login_only': true
}
};

See explainshell: curl -X -d for an explanation of what your curl command actually does.
You send a POST request
You send data using using the content-type application/x-www-form-urlencoded
To replicate that with request you have to configure it accordingly:
var opt = {
url: 'https://tartan.plaid.com/connect',
form: {
// ...
}
};
request.post(opt, function (error, response, body) {
console.log(body)
});
See application/x-www-form-urlencoded for more examples.

Related

Bitbucket OAuth2 using Node.js

I want to have a capability in my application that allows users to Authorize Bitbucket. I have followed https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html.
The following works and brings the Bitbucket authorization screen as expected:
https://bitbucket.org/site/oauth2/authorize?client_id={client_id}&response_type=code
However, this part emits an error about invalid Grant.
$ curl -X POST -u "client_id:secret" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=authorization_code -d code={code}
I am using request module in Node.js and using the code as follows:
request.post(
'https://bitbucket.org/site/oauth2/access_token',
{
json: {
client_id: config.get('app.bitbucket_client_id'),
client_secret: config.get('app.bitbucket_client_secret'),
code: req.query.code,
grant_type: "authorization_code"
}
}, function (error, response, body) {
// Do something here
}
}
{"result":{"error_description":"Unsupported grant type: None","error":"invalid_grant"}}
Please advice!
Found the answer to my question. Basically, Bitbucket expects data to be sent in body directly instead of JSON. Changing from json to form in the code above fixed it for me.

How to call Management API v2 to send verification mail from within a rule?

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.

Parse + Heroku Query 500 Error

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.

Box api call to fetch the access token is failing in node.js

I wrote a program in node.js to fetch the access token to call the box apis, unfortunately I am getting an error "invalid_client" which is either "client ID or secret are wrong" as per the documentation. I am pretty sure that both client id and secret are correct since it worked fine for me while doing ajax calls from UI.
Here is the piece of code I am using
{{{
if(queryData && queryData.code) {
var code = queryData.code;
var data = {
"grant_type" : 'authorization_code',
"client_id" : 'alpha-numeric-id',
"client_secret" : 'alpha-numeric-secret',
"code": 'actual-code-given-in-redirect-uri'
};
var options = {
'url': 'https://www.box.com/api/oauth2/token',
'proxy': 'http://corporate-proxy-url:port',
'headers': {
'accept': 'application/json',
'accept-language': 'en'
},
'json': data,
'timeout': 5000
};
request.post( options, function ( err, response, body ) {
if ( err ) {
console.log("====error====");
} else {
console.log("====success=====");
console.log(response.statusCode);
console.log(body);
}
} );
}
}}}
It would be helpful if someone could figure out whats wrong in my code.
Thanks in advance.
Looks like you're hitting the wrong URL: No www.box.com/api for any API calls AFAIK
According to the documentation, it's app.box.com/api/oauth2/authorize? for your first OAuth2 call to do the Authorize and api.box.com/oauth2/token for the Token call, and all subsequent API calls. api.box.com/2.0/
So step 1 : Authorize:
GET https://app.box.com/api/oauth2/authorize?response_type=code&client_id=MY_CLIENT_ID&state=security_token%3DKnhMJatFipTAnM0nHlZA
Step 1.5 user logs onto Box, and you get called back by Box...
Step 2: Get your token
curl https://app.box.com/api/oauth2/token \
-d 'grant_type=authorization_code&code={your_code}&client_id={your_client_id}&client_secret={your_client_secret}' \
-X POST
Step 3: Call APIs:
curl https://api.box.com/2.0/folders/FOLDER_ID/items?limit=2&offset=0 \
-H "Authorization: Bearer ACCESS_TOKEN"

Body format for Stripe POST operations

I'm accessing the stripe API directly with the REST API (not using a library) but, surprisingly, I can't find documentation on the appropriate body format post data.
Does Stripe expect JSON or form-encoded pairs?
You need to post raw data like key-value pair. (No Json)
e.g.
key1=value1&key2=value2
Make sure you include following in header
Content-Type = application/x-www-form-urlencoded
Here is the sample of the curl code to Nodejs
I am working on a similar problem
as you know we can't send JSON for the "post" method
it must be URL encoded
here is the sample provided by stripe
https://stripe.com/docs/api/checkout/sessions/create
curl https://api.stripe.com/v1/checkout/sessions \
> -u stripe_key_here: \
> -d success_url="https://example.com/success" \
> -d cancel_url="https://example.com/cancel" \
> -d "payment_method_types[]=card" \
> -d "line_items[][name]=T-shirt" \
> -d "line_items[][description]=Comfortable cotton t-shirt" \
> -d "line_items[][amount]=1500" \
> -d "line_items[][currency]=usd" \
> -d "line_items[][quantity]=2"
-u means authorization which we provide in the headers
-d means body of the url
sample code in node js
const fetch = require("node-fetch");
const stripeKey = process.env.STRIPE_KEY;
async function getCheckoutID() {
try {
const endpoint = "https://api.stripe.com/v1/checkout/sessions";
const query = objToQuery({
success_url: "https://example.com/success",
cancel_url: "https://example.com/cancel",
"payment_method_types[]": "card",
"line_items[][name]": "T-shirt",
"line_items[][description]": "Comfortable cotton t-shirt",
"line_items[][amount]": 1500,
"line_items[][quantity]": 1,
"line_items[][currency]": "usd"
});
// enpoint => "https://www.domin.com/api"
// query => "?key=value&key1=value1"
const URL = `${endpoint}${query}`;
const fetchOpts = {
method: "post",
headers: {
"Authorization": `Bearer ${stripeKey}`,
"Content-Type": "application/x-www-form-urlencoded"
}
}
const checkout = await getJSON(URL, fetchOpts);
console.log("CHECKOUT OBJECT : " , checkout);
return checkout;
}
catch(e) {
console.error(e);
}
}
// hepler functions
// instead of using fetch
// getJSON will make it readable code
async function getJSON(url, options) {
const http = await fetch(url, options);
if (!http.ok) {
console.log(http);
throw new Error("ERROR STATUS IS NOT OK :");
}
return http.json();
}
// convert JS object to url query
// {key:"value" , key1: "value1"} to "key=value&key1=value1"
function objToQuery(obj) {
const query = Object.keys(obj).map( k => `${k}=${obj[k]}`).join("&");
return query.length > 0 ? `?${query}` : "";
}
Form encoded pairs
The docs for cURL provide good examples. They're just feeding form encoded key/value pairs via the -d switch via cURL on the command line. Just make sure you use your test secret key so you don't screw up any live data. Then you can play around all you want.
The returned data is JSON.
Here is an example cURL charge using a test card:
curl https://api.stripe.com/v1/charges -u your_test_key: -d card[number]=4000056655665556 -d card[exp_month]=11 -d card[exp_year]=2020 -d amount=100 -d currency=eur -d description="Stripe cUrl charge test"
Exchange your_test_key with your stripe test key.
Remember to keep the : after your key to not get asked for a password.

Resources