Node.js catch empty POST request body - javascript

I am trying to catch a POST request with an empty body before it causes my server to crash. I've seen people using bodyparser but I am using the MVC model and basically I don't have references to app in this .js file.
var resource = req.body;
if(!resource) return res.status(400).send("Your request is missing details.");
I was told to try something like this but it still does not work. When I console.log resource it appears as "{}" even when no body was added in postman, so the null check doesn't work. If anyone has any advice I would appreciate it!

You can use:
if(Object.keys(req.body).length === 0)
or Object.getOwnPropertyNames(req.body).length == 0
And then your logic to respond to the user.

Related

"redirect_uri_mismatch" when sending authentication code to GoogleAPI

I am having trouble with the authentication process for the GoogleAPI. In the end I want to be able to read the users steps using the GoogleFit API and then store that value in a database. Currently I'm using restdb.io and executing javascript in codehooks.
The documentation from Google that I am following can be found here, clicking on the HTTP/REST option in the code examples. At the moment I am at step 5: I have gotten the users authentication code and stored it in the database. Now I have to POST the code along with some other parameters and get the access and refresh tokens.
If the POST is successful (from what I understand) I should get back a 200-OK message that the request was valid. Google will then POST a JSON body with the access and refresh token to the redirect_uri that I have specified in my GoogleAPI credentials page and the initial request. At redirect_uri I have to handle the request and save the two values.
The problem is that I receive a redirect_uri_mismatch - Bad Request message from Google as a response when executing the request. I get it at the log.debug("ERROR HERE: " + [...]); in the code below:
async function mainFunction(){
const authCode = THIS_IS_MY_AUTHENTICATION_CODE;
try {
var answer = await postRequestToGoogle(authCode);
//do stuff with response from Google
} catch (error) {
//do stuff
}
}
async function postRequestToGoogle(authCode){
//body for the request
const params = "code=" + authCode + "&" +
"client_id=THIS_IS_MY_CLIENT_ID" + "&" +
"client_secret=THIS_IS_MY_CLIENT_SECRET" + "&" +
"redirect_uri=THIS_IS_MY_REDIRECT_URI" + "&" +
"grant_type=authorization_code";
try{
const result = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: params})
.then(res => {
log.debug("ERROR HERE: " + JSON.stringify(res.json()));
return res.json();
})
//return JSON back main function
return result;
}catch(error){
//do stuff
}
}
I looked up the error message and tried some things:
Copy and pasted multiple different Authorized redirect URI from the GoogleAPI credentials page into the code to make sure that there is no problem with
http/https
www/no www
trailing slashes
typos or capitalization
Waited for changes to be processed by Google (read that it can more than 30min)
Changed all the other parameters to see if the redirect_uri is actually the problem
If code is changed the message is invalid_grant - Bad Request
If client_id is changed the message is invalid_client - The OAuth client was not found
If client_secret is changed the message is invalid_client - Unauthorized
If the grant_type is changed the message is unsupported_grant_type - Invalid grant_type
That's why I think the issue is the redirect_uri, but it's unclear to me how since I copy&pasted it. Something that came to mind was that maybe the value of redirect_uri gets changed when it's read by Google? Or maybe when the request is being put together? Do some characters have to be replaced?
I tried to analyze the request with Wireshark but didn't think about the fact that it's HTTPS so I would have I would have to decrypt it.. Is that something I should look into?
Thank you for taking the time to read all of this! If you have any advice please let me know :)
Update 16.11.20:
I have created a new OAuth 2.0 Client ID and used the new id/secret in my request. The resulting message the same as before. I will wait and try again tomorrow to see if maybe Google needs some more time. Then I'll try to delete all current IDs and start with a fresh GoogleAPI project.
Update 19.11.20:
Creating a new OAuth 2.0 Client ID did not resolve my problem, neither did creating a whole new GoogleAPI project and adding those credentials into the request. I am in contact with the developers of restdb.io and have asked them to add the Google Auth Library: Node.js Client to the list of supported Node.js packages. Hopefully that will help, I will give it a try as soon as it can be used :)
Update 02.12.20:
No progress so far, but I'm optimistic that the developers will add the package soon. I will post a final update as soon as I am done with this project.

Zapier custom response object

Working on creating a custom zapier integration using zapier CLI. My API endpoint is not technically a create, but it uses the POST method so I made it under the create definition in zapier. I set my output fields to empty, but it breaks on my empty response object.
outputFields: []
The error message:
We had trouble sending your test through.
Unexpected end of JSON input
Hide details
Troubleshooting Errors | Contact Support
What happened (You are seeing this because you are an admin):
Starting POST request to https://api.fake.com/v2/demo-finance/live/csh-search
Received 202 code from https://api.fake.com/v2/demo-finance/live/csh-search after 596ms
Received content ""
Unexpected end of JSON input
Everything is working as expected the request went through it is just not happy with the empty string response not being valid JSON. Is there some way to tell zapier this is an acceptable response object?
David here, from the Zapier Platform team.
It's fine if your API works that way, but you still need to return something json serializable from your function. Try something like this:
const performCreate = async (z, bundle) => {
const response = await z.request('https://api.fake.com/v2/demo-finance/live/csh-search')
if (response.statusCode === 202) {
return {}
}
// handle errors, other cases, whatever
// just make sure to return an object
}
As a side note, just because the request uses a POST request doesn't mean it needs to be a Create; it should be whatever type makes the most sense for the operation. If it's a search (like the fake url suggests) a search is probably the way to go.

RapidAPI response body shows as "undefined"

I'm using the webcams.travel API from RapidAPI (link to API doc) and I've set everything up using browserify, unirest, node, require, etc.
The API response is in json and the Response Header is being output, but the Response Body is supposed to give me an object with webcams, but instead it shows as "undefined". This is my output now:
image of the console output
Is the problem in the parsing of the json, or does it have something to do with unirest?
I'm thankful for any help.
Code in my app.js (which is the suggested request snippet from the API site):
var unirest = require('unirest');
unirest.get("https://webcamstravel.p.rapidapi.com/webcams/list/continent=AN?lang=en&show=webcams%3Aimage%2Clocation")
.header("X-RapidAPI-Key", "MY_RAPID_API_KEY")
.end(function (result) {
console.log(result.status, result.headers, result.body);
});
Following up because I got interest—I eventually solved this issue when I encountered it with Imgur’s API by using the Fetch API instead of Unirest. There seems to be some issue with RapidAPI and Unirest, but when I contacted support they were unaware of any issues.
I recommend trying fetch() if you’re still encountering this.

Facebook Messanger Bot Webhook issue

I received this message
Your Webhooks subscription callback URL has not been accepting
updates.
We've noticed that your Webhooks subscription for callback URL
https://trololo.herokuapp.com/bot has not been accepting updates
for at least 16 minutes. Please verify that your callback server is
functioning so you may continue to receive updates. If you need to
update your callback URL, see
https://developers.facebook.com/docs/graph-api/reference/app/subscriptions#update
If your callback URL continues to fail to accept updates for 8 hours
straight, we will disable your subscription. To reactivate the
subscription, make a POST request with the same parameters, and it
will be reactivated.
This code is executed on the server
app.post('/bot', function (req, res) {
console.log('post bot: ' + req);
var messaging_events = req.body.entry[0].messaging;
for (var i = 0; i < messaging_events.length; i++) {
var event = req.body.entry[0].messaging[i];
var sender = event.sender.id;
if (event.message && event.message.text) {
text = event.message.text;
console.log('text received: ' + text);
sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
}
}
res.sendStatus(200);
});
But it fails because req.body is undefined. The req params is also no json because it makes this error:
TypeError: Converting circular structure to JSON
req only shows [object Object] and I have no idea whats inside the object. .toString isn't working either.
I made the complete guide twice. I think the issue comes from the part were the facebook page should connect to the facebook app. I do this with curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<mytoken>" Please help. Any response is greatly appreciated.
Here is a demo log
I think it's a dependency problem... maybe you're missing the json body parser body-parser
If you look at comments on program sample on node-wit/examples/messenger.js, you will see that you need install some deps:
in your project directory, try:
npm install body-parser express request
And look at: https://www.youtube.com/watch?v=zFO1cRr5-qY ... I think they resolved exactly this issue and others that you may find.

React/Redux + super agent, first call gets terminated

I am writing a react-redux app where I am making some service calls in my middlewares using superagent. I have found a very strange behavior where the first call to my search api always gets terminated. I have tried waiting 10-30 seconds before making the first call, and logging every step along the process and I cannot seem to pinpoint why this is happening.
My action creator looks like
export function getSearchResults(searchQuery) {
return {
query: searchQuery,
type: actions.GO_TO_SEARCH_RESULTS
}
}
It hits the middleware logic here :
var defaultURL = '/myServer/mySearch';
callPendingAction();
superagent.get(defaultURL)
.query({query: action.query})
.end(requestDone);
//sets state pending so we can use loading spinner
function callPendingAction() {
action.middlewares.searchIRC.readyState = READY_STATES.PENDING;
next(action);
}
//return error or response accordingly
function requestDone(err, response) {
console.log("call error", err);
const search = action.search;
if (err) {
search.readyState = READY_STATES.FAILURE;
if (response) {
search.error = response.err;
} else if (err.message) {
search.error = err.message;
} else {
search.error = err;
}
} else {
search.readyState = READY_STATES.SUCCESS;
search.results = fromJS(response.body);
}
return next(action);
}
The query is correct even when the call is terminated, I get this err message back :
Request has been terminated
Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.
at Request.crossDomainError (http://localhost:8000/bundle.js:28339:14)
at XMLHttpRequest.xhr.onreadystatechange (http://localhost:8000/bundle.js:28409:20)
It appears the page refreshes each time too.
I cannot seem to find any clues as to why this happens, it seems not matter what the first call fails, but then it is fine after that first terminated call. Would appreciate any input, thanks!
UPDATE: so it seems this is related to chrome, I am on Version 47.0.2526.80 (64-bit). This app is an iframe within another app and I believe that is causing a problem with chrome because when I try this in firefox there is no issue. What is strange is only the first call gives the CORS issue, then it seems to be corrected after that. If anyone has input or a workaround, I would greatly appreciate it. Thanks for reading.
Had the same problem, just figured it out thanks to the answer provided by #KietIG on the topic ReactJS with React Router - strange routing behaviour on Chrome.
The answer had nothing to do with CORS. The request was cancelled because Chrome had navigated away from the page in the middle of the request. This was happening because event.preventDefault() had not been called in one of the form submit handlers. It seems Chrome handles this differently than other browsers.
See the answer link above for more detail.
In my case this was happening when I tried to set a random HTTP request header (like X-Test) on the client side and either AWS Lambda rejected it during the OPTIONS request or something else did that.
I don't know about the side effects, but you're getting CORS errors. Add the .withCredentials() method to your request.
From the superagent docs:
The .withCredentials() method enables the ability to send cookies from
the origin, however only when "Access-Control-Allow-Origin" is not a
wildcard ("*"), and "Access-Control-Allow-Credentials" is "true".
This should fix it:
superagent.get(defaultURL)
.query({query: action.query})
.withCredentials()
.end(requestDone);
More information on Cross Origin Resource Sharing can be found here.

Categories

Resources