How to resolve Empty error with status code 500 axios? - javascript

this is my code :
Express Routes:
router.route('/block')
.post(controller.ticketBlocking);
Express Controller:
const axios = require('axios');
const OAuth = require('oauth-1.0a');
const crypto = require('crypto');
const ticketBlocking = (req, res) => {
const data = JSON.stringify({
source = req.body.source
});
const oauth = OAuth({
consumer: {
key: '....', //Hided the key
secret: '....', //Hided the secret
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
}
});
const request_data = {
url: 'http://link.vvv/blockTicket',
method: 'post',
};
axios({
method: request_data.method,
url: request_data.url,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
...oauth.oauth.toHeader(oauth.oauth.authorize(request_data)),
},
data : data
})
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
} else if (error.request) {
console.log(error.request);
} else {
console.log('Error', error.message);
}
console.log(error.config);
});
};
the npm package which am using is - "oauth-1.0a"
The problem am facing is, when i use GET method with different end point, i get an output but when ever i use POST method am getting an empty error with status code 500
I dont know where is the mistake, am using oauth1.0a for authorization, please help !

Related

Put Not Working to Update with Axios Mongoose

I am trying to set up an edit feature to edit a post. Right now I am trying to update a specific post by ID and then I'll make it dynamic.
I can get axios to send the PUT request but I don't receive any indication that it is received on the router. Also the ID I have set it showing up correctly in the URL.
I'm not sure how to send the data over to the router so it can find the ID.
Edit component
function handleSubmit(event){
event.preventDefault()
axios ( {
url: `/api/${props.data[0]._id}`,
method: 'PUT',
headers: { "Content-Type": "multipart/form-data" },
id: props.data[0]._id
})
.then(() => {
console.log(`data has been sent to the server from axios: ${props.data[0]._id}`)
})
.catch(() => {
console.log('Data could not be sent from axios')
})
}
Router
router.put('/:id', async (req, res) => {
try {
const updatedGratitude = await PostGratitude.findByIdAndUpdate(req.params.id)
res.status(200).json(updatedGratitude)
} catch (err){
next(err)
}
})
if you are editing a post then you should send the data in the request as well
like a title: "" and description: "" or something and in the in the router, you could write something like this :
function handleSubmit(event) {
event.preventDefault()
axios({
url: `/api/${props.data[0]._id}`,
method: 'PUT',
headers: { "Content-Type": "application/json" },
data: {
title: '',
description: ''
}
})
.then((response) => {
console.log(response)
})
.catch((err) => {
console.log(err)
})
}
you need to pass the arguments as to what to update as well, here is an example of a code that I wrote
router.put('/updatentry/:id',fetchuser, async (req, res) => {
var success = false
try {
const { title, description } = req.body
let newentry = { title: title , description: description
}
let old_entry = await Journal.findById(req.params.id);
if (!old_entry) {
return res.status(404).send({ success, error: 'Not Found'})
}
const update_entry = await Journal.findByIdAndUpdate(req.params.id, { $set: newentry }, { new: true })
return res.send(res: update_entry)
} catch (error) {
return res.status(500).send(error: 'Internal Server Error')
}
})
This is because you forgot the update body on method. Try this:
PostGratitude.findByIdAndUpdate(req.params.id, req.body)
instead of :
await PostGratitude.findByIdAndUpdate(req.params.id)
Because mongoose can not know what to update :D

how to fix uri undefined error when trying to send request

when I'm trying to call the request in front node, I'm getting error in my backend node " RequestError: Error: Invalid URI "undefined"" , it seems like backend node request is not getting the data form my frontend node request.
knowing that uploadLink already have a value and in my browser console the frontend request looks ok
my backend request code
const ThumbnailUpload = async (req, res) => {
const { Uploadlink } = req.body;
const { selectedFile } = req.body;
const clientServerOptions = {
uri: `${Uploadlink}`,
body: JSON.stringify({
name: selectedFile,
}),
method: 'PUT',
headers: {
'Content-Type': ' application/json',
Accept: 'application/vnd.vimeo.*+json;version=3.4',
Authorization: getVimeoAuthorization(),
},
};
request(clientServerOptions, function (error, response) {
if (error) {
res.send(error);
} else {
const body = JSON.parse(response.body);
res.send(body);
}
console.log(Uploadlink);
});
};
and my frontend code is
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData();
formData.append(
'selectedFile',
new Blob([selectedFile], { type: 'image/jpg, image/png, or image/gif' }),
);
formData.append('uploadLink', uploadLink);
const headers = {
'Content-Type': 'image/jpg, image/png, or image/gif',
Accept: 'application/vnd.vimeo.*+json;version=3.4',
};
try {
axios
.post(`${backendPostPath}/thumbnail-upload`, formData, {
headers,
})
.then((response) => {
applyThumbnial();
console.log(response);
});
} catch (error) {
console.log(error);
}
};
any advise ?
change:
const { Uploadlink } = req.body;
to:
const { uploadlink } = req.body;
make variable consistent throughout the code
EDIT
also, since you're uploading a file, you need to use upload middleware before request handler, and file will be within req.file:
route.post('/thumbnail-upload', upload.single('selectedFile'), ThumbnailUpload);
//... handler..
const selectedFile = req.file;

node.js oauth-1.0a working for Twitter API v1.1 but not for v2

I've found this function to generate oauth-1.0a header:
// auth.js
const crypto = require("crypto");
const OAuth1a = require("oauth-1.0a");
function auth(request) {
const oauth = new OAuth1a({
consumer: {
key: process.env.TWITTER_API_KEY,
secret: process.env.TWITTER_API_SECRET_KEY,
},
signature_method: "HMAC-SHA1",
hash_function(baseString, key) {
return crypto.createHmac("sha1", key).update(baseString).digest("base64");
},
});
const authorization = oauth.authorize(request, {
key: process.env.TWITTER_ACCESS_TOKEN,
secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
});
return oauth.toHeader(authorization).Authorization;
}
module.exports = auth;
It works fine if I try it with Twitter API v1.1:
// v1.js
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = "https://api.twitter.com/1.1/favorites/create.json";
const method = "POST";
const params = new URLSearchParams({
id: "1397568983931392004",
});
axios
.post(url, undefined, {
params,
headers: {
authorization: auth({
method,
url: `${url}?${params}`,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
But if I try it with Twitter API v2:
// v2.js
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = `https://api.twitter.com/2/users/${process.env.TWITTER_USER_ID}/likes`;
const method = "POST";
const data = {
tweet_id: "1397568983931392004",
};
axios
.post(url, data, {
headers: {
authorization: auth({
method,
url,
data,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
it fails with:
{
title: 'Unauthorized',
type: 'about:blank',
status: 401,
detail: 'Unauthorized'
}
I tried encoding the body of the request as suggested here, but get the same error:
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const querystring = require("querystring");
const url = `https://api.twitter.com/2/users/${process.env.TWITTER_USER_ID}/likes`;
const method = "POST";
const data = percentEncode(
querystring.stringify({
tweet_id: "1397568983931392004",
})
);
function percentEncode(string) {
return string
.replace(/!/g, "%21")
.replace(/\*/g, "%2A")
.replace(/'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29");
}
axios
.post(url, data, {
headers: {
"content-type": "application/json",
authorization: auth({
method,
url,
data,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
If tested with Postman, both endpoints (1.1 and 2) work fine with the same credentials.
Any ideas on what am I doing wrong while using v2 or how to get it working with Twitter API v2?
I suspect it's something related with the body of the request as that's the main diference between both requests, but haven't been able to make it work.
Figure it out, the body of the request should not be included while generating the authorization header:
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = `https://api.twitter.com/2/users/${process.env.TWITTER_USER_ID}/likes`;
const method = "POST";
const data = {
tweet_id: "1397568983931392004",
};
axios
.post(url, data, {
headers: {
authorization: auth({
method,
url,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
Basically, when making a post request to Twitter API v1.1, the data should be encoded, should be used to generate the authorization header, and the post request should be sent as application/x-www-form-urlencoded.
When making a post request to Twitter API v2, the data should not be encoded, should not be included while generating the authorization header, and must be sent as application/json.
Hope this becomes helpful to someone else.

How to authenticate using bearer token using got.js

I'm trying to switch from request.js to got.js. I expect to see the got.js implementation authenticate similarly to how the request.js library does. But, instead, I get the following error.
auth no longer supported. Replaced by username and password.
There is no mention of bearer tokens on the docs page.
So how do I authenticate my request using bearer tokens using got.js? Or what am I doing wrong?
Current code: request.js, working
const request = require('request');
const module.exports = config => {
const options = {
auth: {
bearer: config.secret,
},
};
const result = await new Promise(( resolve, reject, ) => {
request.get( url, options, ( error, response, body, ) => {
...
New code: got.js, throws error
const got = require('got');
module.exports = async config => {
const options = {
auth: {
bearer: config.secret,
},
};
const result = await got(url, options);
...
}
This should be worked, if I'm not wrong
let token = 'your token'
const options = {
headers: {
'Authorization': `Bearer ${token}`
}
};
worked for me !!
router.get('/product', (req,res)=>{
const dataStream = got.stream({
url: "http://localhost:8000/products",
method: "GET",
hooks: {
beforeRequest: [
options => {
var token= 'Bearer ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2MTkzODA0NjIsImV4cCI6MTYxOTM4NDA2Mn0.JoJbRpPniGuMbwULEtts7I19QxEImvarT6AoqVuNb9w'
options.headers['Authorization'] = token;
}
]
}
});
pipeline(dataStream, res, (err) => {
if (err) {
console.log(err);
res.sendStatus(500);
}
});
});

Using request-promise to make an API call using jwt. [ERR_INVALID_ARG_TYPE] received

I'm learning nodejs and trying to make an API call. The API uses JWT to authenticate.
I created these functions to sign a token:
function token() {
const payload = {
iat: Math.floor(new Date() / 1000),
exp: Math.floor(new Date() / 1000) + 30,
sub: "api_key_jwt",
iss: "external",
jti: crypto.randomBytes(6).toString("hex")
};
return new Promise((resolve, reject) => {
jwt.sign(payload, privatekey, { algorithm: "RS256" }, function(
err,
token2
) {
if (err) reject(err);
else resolve(token2);
});
});
}
exports.genToken = async function() {
const header = {
"x-api-key": api
};
const data = {
kid: api,
jwt_token: await token()
};
async function authorization(req, res) {
try {
const auth = await rp({
url: authurl,
method: "POST",
headers: header,
body: data
});
res.send(auth.body);
} catch (error) {
res.send(404).send();
}
}
return {
"x-api-key": api,
Authorization: "Bearer " + authorization()
};
};
This works fine. Then I created a function to make the API call:
const token = require("./index").genToken;
const rp = require("request-promise");
exports.getOrderBook = function(res, error) {
const full_url = url + "order_book";
const auth = token();
rp({
url: full_url,
method: "GET",
headers: auth,
body: {
market: "btceur"
},
json: true
})
.then(function(response) {
res(response);
})
.catch(function(err) {
error(err);
});
};
And I call it using Express:
routes.get("/orderbook", async (req, res, next) => {
try {
const book = await orders.getOrderBook();
res.send(book);
} catch (error) {
next(error);
}
});
However, when I call my API, it shows an error in console:
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of
type string or Buffer. Received type object.
I guess the error is something with the token generation, because if I console.log(auth) in the getOrderBook function, it shows Promise { <pending> }, so probably an object is being passed as the jwt token.
Is it really the problem? I tried a lot of different solutions that I found on internet, however the concept of Async/Await is new to me, and I'm having some troubles to figure it out.
Thanks a lot in advance guys!
Since getToken is an anync function, the return is wrapped in a Promise as well so you would need another anync/await:
exports.getOrderBook = async function() {
let response;
try {
const full_url = url + "order_book";
const auth = await token();
response = await rp({
url: full_url,
method: "GET",
headers: auth,
body: {
market: "btceur"
},
json: true
});
} catch (e) {
// handle error
throw e
// or console.error(e)
}
return response;
};
In this line as well Authorization: "Bearer " + authorization(), authorization is returning a promise
const bearer = await authorization()
return {
"x-api-key": api,
Authorization: "Bearer " + bearer
};
For error handling wrap entire thing in try..catch block
exports.genToken = async function() {
try {
const header = {
"x-api-key": api
};
const data = {
kid: api,
jwt_token: await token()
};
async function authorization(req, res) {
let auth;
try {
auth = await rp({
url: authurl,
method: "POST",
headers: header,
body: data
});
// res object not available
// res.send(auth.body);
} catch (error) {
// res object not available, better throw error and handle in your middleware
// res.send(404).send();
}
return auth
}
const bearer = await authorization()
} catch (e) {
// handle error
}
return {
"x-api-key": api,
Authorization: "Bearer " + bearer
};
}

Categories