ERR_HTTP_HEADERS_SENT in Nodejs Server (AWS) - node.js

I'm asking again with this code provided Please Help Thank you. I am calling this API with Firebase function from Android using okhttp3, here the code below. I already subscribed to a plan in firebase to call external API
Firebase Cloud Function Code
exports.CustomerProfile = functions.https.onRequest((req, res) => {
const options = {
method: "POST",
uri: "http://3.xxxx.xx.xx2:3000/api/customers/profile",
formData: {
session_token: req.body.session_token
},
headers: {
"content-type": "application/x-www-form-urlencoded",
"x-auth-token": "xxxxxxE"
},
resolveWithFullResponse: true,
json: true,
simple: false
};
rp(options)
.then(function(response) {
res.send(response.body);
})
.catch(function(err) {
res.send(err);
});
});
API CODE
router.post("/profile", async (req, res) =>{
const customers = new Customers();
var data = req.body;
var token = req.body.session_token;
customers.findBySessionToken(token, (err, result) => {
if (!err) {
if(result[0].provider === 'gmail'){
var gmail = result[0].access;
customers.findByGmail(gmail, (err, result) => {
res.status(200).send(result);
});
}else if(result[0].provider === 'facebook') {
var facebook = result[0].access;
customers.findByFb(facebook, (err, result) => {
res.status(200).send(result);
});
}else if(result[0].provider === 'mobile') {
var mobile = result[0].access;
customers.findByMobile(mobile, (err, result) => {
res.status(200).send(result);
});
}
} else {
if (err.code === "ER_SIGNAL_EXCEPTION") {
res.status(400).send([{ message: err.sqlMessage }]);
} else {
res.status(400).send(err);
}
}
});
});

this means that you have already sent a response res.send... somewhere else , you cant do more than one response for a request.

Related

How to send cookies with fetch and fix 404 post error?

How to send cookies with fetch and fix 404 post error?
Hello. I'm trying to send a post to a server that uses a jwt token for authorization, but I get a post 404.
Here is the logic for setting the token and the user:
app.use((req, res, next)=>{
const jwtToken = req.cookies.JWT_TOKEN;
if(!jwtToken) {
next();
return;
}
jwt.verify(jwtToken, SECRET, (err, decoded)=>{
if(err) {
next(err);
return;
}
const sessionData = decoded.data;
let userId;
if (sessionData['modx.user.contextTokens']) {
if (sessionData['modx.user.contextTokens']['web'] > 0) {
userId = sessionData['modx.user.contextTokens']['web'];
}else if($dataarr['modx.user.contextTokens']['mgr'] > 0) {
userId = sessionData['modx.user.contextTokens']['mgr'];
} else {
return redirect('/signin');
}
}
req.user = {userId};
next();
});
});
app.use((req, res, next)=>{
if (!req.user || !req.user.userId) {
next(new Error('Access Denied'));
} else {
next();
}
});
Here is the get request that was already here and it works:
app.get("/:id?", function(req, res){
const room = {id:parseInt(req.params.id||0)};
const userid = req.user.userId;
console.log('USEEEEEEEEEEEEEEEEEEEEEEEEEER ID', userid);
pool.query("SELECT * FROM modx_user_attributes WHERE id = ?", [userid], function(err, [userData]) {
if(err) return console.log(err);
//console.log('userData', userData);
const token = jwt.sign({
data: {userId: userid},
}, SECRET);
res.render("index.hbs", {
appdata: {token, room, user: userData},
final scripts,
});
});
});
And here is my point, but I can't reach it:
app.post('/writeVideo', (req, res) => {
req.video.mv('test.wav', (err) => {
if (err) {
res.send(err);
} else {
res.send({
success: 'file write'
})
}
});
})
And here I am trying to knock on the point:
fetch('/writeVideo', {
method: 'POST',
credentials: "same-origin",
headers: {
'Content-type': 'application/json',
},
body: {
user: {
userId: 8
},
video: audioBlob
}
}).then(data => data.json()).then(data => console.log(data));
I read a little, they advise just using credentials: 'same-origin' || 'include', however it didn't work for me, I tried setting Cookie headers: 'JWT_TOKEN=token' in different ways - didn't work. Please tell me how should I proceed.
Thank you.

NextJs - Function in API folder in pages gives 'res.status is not a function' error

I'm using NextJs and I'm trying to create a subscription form that sends data to MailChimp. However, I'm getting error which says
res.status is not a function
This file is inside my pages/api directory. What might be going wrong?
import { subscribe } from "../../lib/api";
const request = require("request");
export default async function subscribeWithEmail(req, res) {
const { email, js } = req.body;
const mcData = {
members: [
{
email_address: email,
status: "pending",
},
],
};
const mcDataPost = JSON.stringify(mcData);
const options = {
url: "https://us6.api.mailchimp.com/3.0/lists/SECRET",
method: "POST",
headers: {
Authorization: "auth APIKEY",
},
body: mcDataPost,
};
if (email) {
request(options, (err, res, body) => {
console.log(res);
if (err) {
res.json({ error: err });
} else {
if (js) {
res.status(200).send({ message: "yay" });
} else {
res.redirect("/");
}
}
});
} else {
res.status(404).send({ message: "Failed" });
}
// res.status(200).json(data);
return res.status(200);
}
You are shadowing your initial res variable.
// you have another res here, which has nothing to do with Next.js res, but it is overriding it
// So you need to rename it to something else, for example to "response"
request(options, (err, response, body) => {
console.log(response);
if (err) {
res.json({ error: err });
} else {
if (js) {
res.status(200).send({ message: "yay" });
} else {
res.redirect("/");
}
}
});

How to redirect after an execution of a paypal payment?

I followed the instructions on how to add the smart payment buttons from PayPal (https://developer.paypal.com/docs/checkout/integrate/) by using the SDK API. Everything works fine except that I can't redirect the buyer after the execution of the payment.
The JS code in the HTML page looks like this:
paypal.Buttons({
createOrder: function (data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: price
}
}]
});
},
onApprove: async function (data, actions) {
return actions.order.capture().then(function (details) {
alert('success!');
return fetch('/paypal-transaction-complete', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
orderID: data.orderID,
})
});
});
}
}).render('#paypal-button-container');
On the server side I execute it with async functions and wait for the promise by using the arrow functions:
app.post('/paypal-transaction-complete', function (req, res) {
paypalRequestHandler.handleRequest(req, res)
.then(() => {
res.redirect('/'); // not working
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
I'm wondering why it's not redirecting, I can do stuff like console.log() but it just won't redirect the buyer.
To answer my own question: after getting the promise on the server side, a response code should be returned to the client, then on the client side the location of the page can be changed. So in my case it looks like this on the server side:
app.post('/paypal-transaction-complete', function (req, res) {
paypalRequestHandler.handleRequest(req, res)
.then(() => {
res.sendStatus(200);
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
On the client side:
paypal.Buttons({
createOrder: function (data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: price
}
}]
});
},
onApprove: async function (data, actions) {
return actions.order.capture().then(function (details) {
alert('success!');
const responsePromise = fetch('/paypal-transaction-complete', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
orderID: data.orderID,
})
});
responsePromise.then(function (responseFromServer) {
if(responseFromServer.status === 200) {
location.href = 'success_page';
} else {
alert('smth went wrong');
location.href = '/';
})
}
});
});
}
}).render('#paypal-button-container');

TypeError: req.post is not a function

In my server.js under signup route after registering the user I want to send a verification email and a verification sms. But the smsService request trows an error. I am not sure what's wrong.
Can you help me to spot the error?
server.js:
app.post('/signup-user', upload.single('avatar'), (req, res) => {
let sAvatarImagePath = req.file.path.split("public/").pop()
let token = jwt.sign({
username: req.body.email,
}, 'supersecret', {
expiresIn: 240
});
user.createUser(req.body, sAvatarImagePath, (err, jResult) => {
if (err) {
return res.send(jResult)
}
mailer.sendEmail(res, req.body, token)
smsService.sendSms(req, res, (err, jResult) => {
if (err) {
return res.send(jResult)
}
})
return
})
})
smsService.js:
var smsService = {}
smsService.sendSms = (req, res, fCallback) => {
const sUrl = 'http://smses.io/api-send-sms.php';
const sToken = '$2y$10$//Qx9DsrDCIeNeWIjr1V.uWRR3m9raVGJNN4iDRZsxNDxknvCJsPC';
let sRecipientNbr = req.body.mobile_number;
let sMessage = '5678'
console.log('CALLING SMS API...', sRecipientNbr);
req.post(
sUrl, {
form: {
action: 'SEND',
mobile: sRecipientNbr,
message: sMessage,
apiToken: sToken,
},
},
(err, res, body) => {
if (err) {
console.log('ERROR WHEN CALLING SMS API', err);
return fCallback({
error: true,
message: 'System is currently unavailable'
});
}
var jResponse = safeJsonParse(body);
console.log('SMS API return:', jResponse);
if (jResponse.status != 'ok') {
console.error('SMS API RETURNED ERROR', err, jResponse);
return fCallback({
error: true,
message: 'System is currently unavailable'
});
}
return fCallback(false);
},
);
}
module.exports = smsService
I think you are confused between express Request object and NodeJS request module. You need to install NodeJS request module to make external http request
npm install request --save
and then use in service smsService.js
var request = require('request');
var smsService = {}
smsService.sendSms = (req, res, fCallback) => {
const sUrl = 'http://smses.io/api-send-sms.php';
const sToken = '$2y$10$//Qx9DsrDCIeNeWIjr1V.uWRR3m9raVGJNN4iDRZsxNDxknvCJsPC';
let sRecipientNbr = req.body.mobile_number;
let sMessage = '5678'
console.log('CALLING SMS API...', sRecipientNbr);
request.post(
sUrl, {
form: {
action: 'SEND',
mobile: sRecipientNbr,
message: sMessage,
apiToken: sToken,
},
},
(err, res, body) => {
if (err) {
console.log('ERROR WHEN CALLING SMS API', err);
return fCallback({
error: true,
message: 'System is currently unavailable'
});
}
var jResponse = safeJsonParse(body);
console.log('SMS API return:', jResponse);
if (jResponse.status != 'ok') {
console.error('SMS API RETURNED ERROR', err, jResponse);
return fCallback({
error: true,
message: 'System is currently unavailable'
});
}
return fCallback(false);
},
);
}
module.exports = smsService
I hope this will help you

Node Server unable to respond to PUT request

I am making a quite easy CRUD application in MEAN stack.
I have succesfully done all but Update function. Problem is not with request itself but inability of Node server to respond. Request is making changes to database as requested and I even eget a { n: 1, nModified: 0, ok: 1 } response from mongojs.
However, I am unable to send it back to Angular frontend.
I try res.json() but it won't all allow me as it is a not a function? But I am succesfuly doing res.json in create, delete and read. In network tab in developers console, request seems to be pending and after like 30 seconds it throws an error.
No luck with postman either.
How can I send a response to frontend?
// Error handling
const sendError = (err, res) => {
response.status = 501;
response.message = typeof err == 'object' ? err.message : err;
res.status(501).json(response);
};
// Response handling
let response = {
status: 200,
data: [],
message: null
};
// Update log <-- doesn't send response but works
router.put('/update/:id', (req, body, res) => {
console.log("Received UPDATE request");
console.log(req.params.id);
const bodyToUpdate = {
'_id': mongojs.ObjectId(req.params.id),
'week': req.body.week,
'type': req.body.type,
'text': req.body.text,
'days': req.body.days
};
console.log(bodyToUpdate);
db.logs.update({
_id: mongojs.ObjectId(req.params.id)}, bodyToUpdate, (err, res) => {
if (err) return next(err);
response.data = res;
res.json(response);
console.log(response);
});
});
// Delete log <--does work without problems
router.post('/delete/:id', (req, res) => {
console.log("Received DELETE request");
console.log(req.params.id);
db.logs.remove({
_id: mongojs.ObjectId(req.params.id)}, (err, users) => {
if (err) return next(err);
console.log(response);
response.data = users;
res.json(response);
});
});
Service API frontend
deleteLog(id) {
return new Promise((resolve, reject) => {
this._http.post('/api/delete/' + id , id)
.map(res => res.json())
.subscribe(res => {
resolve(res);
console.log(res);
}, (err) => {
reject(err);
});
});
}
updateLog(logToUpdate) {
return new Promise((resolve, reject) => {
this._http.put('/api/update/' + logToUpdate._id, logToUpdate)
.map(res => res.json())
.subscribe(res => {
resolve(res);
// console.log(res);
}, (err) => {
reject(err);
});
});
}
As #JithinSebastian correctly pointed out - I should not have 3 arguments in put request. I also had to change name of callbacks in mongo update function because I already used res in router function callback.
// Update log
router.put('/update/:id', (req, res) => {
console.log("Received UPDATE request");
console.log(req.body);
const bodyToUpdate = {
'_id': mongojs.ObjectId(req.params.id),
'week': req.body.week,
'type': req.body.type,
'text': req.body.text,
'days': req.body.days
};
db.logs.update({
_id: mongojs.ObjectId(req.params.id)
}, bodyToUpdate, (err, logs) => {
if (err) return next(err);
response.data = logs;
res.json(response);
console.log(response);
});
});

Resources