NodeJS res.body is undefined only on one router - javascript

I am sending data using swift to a nodeJS server.
Here is the Swift Code:
var data:[String:String] = [:]
data["ABC"] = "nothing"
let req = HTTPRequest(url_to_request: "https://xxx.xxx.xx.x/update", method: HTTPRequest.HTTPRequestMethod.post, data: Profile.toJSON(dict: data))
Here is the NodeJS:
console.log("Server is up!");
var bodyParser = require('body-parser');
var express = require('express');
var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
var http = require('http');
var https = require('https');
var fs = require('fs');
var bcrypt = require('bcryptjs');
var sslOptions = {
key: fs.readFileSync('key.pem', 'utf8'),
cert: fs.readFileSync('cert.pem', 'utf8'),
passphrase: 'phrase',
rejectUnauthorized: false
};
var app = express();
//Variables:
var httpPort = 8888;
var httpsPort = 8443;
app.use(bodyParser.urlencoded({
extended: false,
limit: '20mb'
}));
app.use(bodyParser.json({
limit: '50mb'
}));
// parse application/json json size limit
// parse application/x-www-form-urlencoded
// setup server
app.set("port_https", httpsPort);
//check secure connection
app.all("*", function(req, res, next) {
console.log("Secure connection: " + req.secure);
if (req.secure) {
return next();
}
res.redirect("https://" + req.hostname + ":" + app.get("port_https") + req.url);
});
// add User
app.post('/register', register);
//signIn
app.post('/login', logIn);
//Update user's profile details.
app.post('/update', updateProfile);
// Request profile details.
app.post('/profile', profileRequest);
function updateProfile(req, res) {
console.log(res.body); // ---> undefined
}
When I send a post request with data to login, profile, register routers res.body is working well. But when I send data to update for some reason req.body is undefined:
ERROR:
Server: Secure connection: true
Server: undefined #----> log of res.body
Server: Connected successfully to databse!
stderr: /home/asaf/NodeJS/IBQA/IBQA_Server/node_modules/mongodb/lib/mongo_client.js:350
throw err
^
TypeError: Cannot read property 'ABC' of undefined
at /*****/server.js:92:33
at connectCallback (*****/mongo_client.js:428:5)
at /*****/node_modules/mongodb/lib/mongo_client.js:347:11
at nextTickCallbackWith0Args (node.js:419:9)
at process._tickCallback (node.js:348:13)
closing code: 1

Your request if there in the req variable, res is used to send the response. Try console.log(req.body)

Related

U2F - TypeError | not able to register key

I've recently started looking at U2F in Node.js and Javascript.
I get the error: TypeError: Cannot read property 'registerResponse' of undefined
Before receiving the error on the server i get the following returned:
{errorCode: 5, errorMessage: "NotAllowedError: The operation either timed out or…://w3c.github.io/webauthn/#sec-assertion-privacy."}
The server is using HTTPS and a self signed cert on localhost in Mac os
What could be the issue? The response seems to be empty; and i dont get asked to insert the usb in the browser.
app.js:
const U2F = require("u2f");
const Cors = require("cors");
const session = require("express-session");
const HTTPS = require("https");
const FS = require("fs");
const BodyParser = require("body-parser");
const express = require("express");
var app = express();
var routes = require("./routes")(app);
const APP_ID = "https://localhost:3000";
app.use(BodyParser.json());
app.use(BodyParser.urlencoded({ extended: true }));
app.use(session({ secret: "thepolyglotdeveloper", cookie: { secure: true, maxAge: 60000 }, saveUninitialized: true, resave: true }));
app.use(Cors({ origin: [APP_ID], credentials: true }));
HTTPS.createServer({
key: FS.readFileSync("server.key"),
cert: FS.readFileSync("server.crt")
}, app).listen(3000, () => {
console.log("Listening at :443...");
});
routes.js
const U2F = require("u2f");
const session = require("express-session");
const APP_ID = "https://localhost:3000";
var appRouter = function(app) {
var user;
app.get("/", function(req, res, next) {
res.sendFile(__dirname + '/index.html');
});
app.get("/register", function(req, res, next) {
var session = U2F.request(APP_ID);
app.set("session", JSON.stringify(session));
console.log("session: " + JSON.stringify(session));
res.send(session);
});
app.post("/register", function (req, res, next) {
console.log("res2: " + req.body);
var registration = U2F.checkRegistration(JSON.parse(app.get("session")), req.body.registerResponse);
if(!registration.successful) {
return res.status(500).send({ message: "error" });
} else {
console.log("error");
}
user = registration;
res.send(registration);
});
}
module.exports = appRouter;
index.html
$("#register").click(() => {
if(window.u2f && window.u2f.register) {
$.get("/register", result => {
console.log(result);
window.u2f.register(result.appId, [result], [], response => {
console.log(response);
$.post("/register", { registerResponse: response }, result => {
console.log(result);
});
console.log(response);
});
});
} else {
document.write("<p>U2F is not supported</p>");
}
});
It seems like the request is timing out, or is not allowed. I've tried looking for the solution and so on; but there is little to no information regarding this issue.
Any help is much appreciated!
You are using var routes = require("./routes")(app); before BodyParser. Middlewares work in the order they are initialised. So, In your case body-parser in not even used in the routes.
Put the routes after bodyParser and cors:
var app = express();
const APP_ID = "https://localhost:3000";
app.use(BodyParser.json());
app.use(BodyParser.urlencoded({ extended: true }));
app.use(session({ secret: "thepolyglotdeveloper", cookie: { secure: true, maxAge: 60000 }, saveUninitialized: true, resave: true }));
app.use(Cors({ origin: [APP_ID], credentials: true }))
var routes = require("./routes")(app);

Error setting cookie and getting a json response with router.post in express, node.js

I'm trying to set a cookie with a post method in order to do some db query and put it back in the cookie value, as well as returning a json with the user data.
It works, the cookie is set and I get the json on http://localhost:8080
but I get a message from the compiler:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
How can I fix it so it won’t make this error?
my file structure is:
root/ app.js
root/controllers/ cookie.controller.js
root/routes/ cookie.route.js
app.js
const express = require('express');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const app = express();
const port = process.env.PORT || process.argv[2] || 8080;
app.use(cookieParser());
app.use(require('./routes/cookies'));
app.use(cors());
app.listen(port, () => console.log('cookie-parser demo is up on port: ' + port));
cookie.route.js
const express = require('express');
const cookieController = require('../controllers/cookies');
const router = express.Router();
router.use(require('cookie-parser')());
router.post('/', router.use(cookieController.getCookie));
module.exports = router;
cookie.controller.js
exports.getCookie = (req, res, next) => {
let auth = req.cookies.auth;
//...db queries, get userData
let userData = {
id: '123',
token: 'sfsdfs34',
email: 'user#gmail.com'
};
// if cookie doesn't exist, create it
if (!auth) {
res.status(200)
.cookie('auth', userData.id)
.json({ message: 'it works!', user: userData });
req.cookies.auth = userData.id;
}
next();
};
You're modifying the request cookie headers after sending the response at the end of your getCookie controller. You should remove req.cookies.auth = userData.id, and use res.cookie() instead before sending the response.
const express = require('express')
const cookieParser = require('cookie-parser')
const app = express()
app.use(cookieParser())
app.get('/', (req, res) => {
if (!req.cookies.auth) {
res.cookie('auth', { id: '123' })
}
res.json({ message: 'It worked!' })
})
app.listen(8080, () => console.log('http://localhost:8080))
Problem was solved after deleting the cors from app.js

How to get JWT token from Express to Angular using ngResource?

I am working with a jwt token to validate user registration. A unique url is sent to user's email and it redirects to the authentication page, the token is decoded on server side and I need to send this json data to angular, on client side. How can I do this using token as query parameter and retrieve it using ngResource?
server.js
'use strict';
var express = require('express');
var app = express();
var router = express.Router();
var bodyParser = require('body-parser');
var nodemailer = require('nodemailer');
var jwt = require('jsonwebtoken');
var moment = require('moment');
var port = process.env.PORT || 5000;
app.use(express.static('./src/client/'));
app.use(express.static('./'));
app.use(express.static('./.tmp'));
app.use('/*', express.static('./src/client/index.html'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// sign with default (HMAC SHA256)
var expires = moment().add(12, 'hours').valueOf();
var token = jwt.sign({
user: 'userdata',
iat: Math.floor(Date.now() / 1000),
expireIn: expires
}, 'thisismysecretstring');
// nodemailer sendMail function
app.post('/sendMail', function(req, res) {
var transporter = nodemailer.createTransport('smtp://b204bf8f6ede15:71b5c1473852e2#mailtrap.io:2525');
var data = req.body;
var mailOptions = {
from: 'noreply#ixfire.com',
to: data.email,
subject: 'Email sent by ' + data.displayName,
html: '<p>Please click on url below to register</p><br>CLICK HERE'
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
res.json(token);
});
// decode token from url parameter
app.get('/auth', function(req, res) {
var token = req.query.token;
try {
var decoded = jwt.verify(token, 'thisismysecretstring');
if (decoded.exp <= Date.now()) {
res.end('Access token has expired', 400);
}
res.json(decoded);
} catch (err) {
console.log(err);
res.json(err);
}
});
// router.use(function(req, res, next) {
// var token = req.query.token;
// try {
// var decoded = jwt.verify(token, 'thisismysecretstring');
// res.json(decoded);
// } catch (err) {
// console.log(err);
// res.json(err);
// }
// });
// app.use('/auth', router);
app.listen(port, function () {
console.log('Express app listening on port: ' + port);
console.log(__dirname);
});
token.js
(function() {
'use strict';
angular
.module('xfire.token', ['ngResource'])
.factory('Token', function($resource) {
return $resource('auth/:token', {
token: '#token'
});
});
})();
url format:
http://localhost:3000/auth/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ2NmYWJyaSIsImlhdCI6MTQ2ODI0NDI1NCwiZXhwaXJlSW4iOjIxNjAwMDAwfQ.5rs1rlWMTTcap4idG-XOU-UiwbU0YzlnAYjm9Vwz-B0
I usually send it in a header, most often I name it x-auth-header.
I don't however use nor I recommend anyone (except for playing around) to use ngResource, as it is limiting.
Personally, I use restangular, with request/response interceptors.
Response interceptor to grab and decode the token, and request interceptor to authorize the request with "Bearer" + tokenString.

POST request is empty using ExpressJS

When I do a POST request to my server's route, the request.body is empty. And I'm using body parser to obtain JSON data. What I'm doing wrong?
On the _saveTicket function, I have console.log to show all the body request parameters. And when I do a POST request, request.body is empty.
What I need to parse it automatically ?
server.js
/**
* Declaration
**/
var express = require('express'),
database = require('./config/database.js'),
morgan = require('morgan'),
port = 2559,
bodyPar = require('body-parser'),
methodOv = require('method-override'),
mongoose = require('mongoose'),
fsr = require('file-stream-rotator'),
logDirectory = __dirname + '/log',
favicon = require ('serve-favicon');
app = express();
/**
* DB Connection
**/
mongoose.connect(database.mongo);
/**
* Api definition
**/
var accessLogStream = fsr.getStream({
date_format: 'YYYYMMDD',
filename: logDirectory + '/access-%DATE%.log',
frequency: 'daily',
verbose: false
})
app.use(express.static(__dirname + '/public'));
app.use(morgan('combined', {stream: accessLogStream}));
app.use(bodyPar.urlencoded({'extended':'true'}));
app.use(bodyPar.json());
app.use(bodyPar.json({ type: 'application/vnd.api+json' }));
app.use(methodOv('X-HTTP-Method-Override'));
app.use(favicon(__dirname + '/public/images/favicon.ico'));
/**
* Routes section
**/
require('./routes/ticket.js')(app);
/**
* Starting server
**/
app.listen (port)
console.log ("Listening on port: " + port);
model/ticket.js
var mongoose = require('mongoose');
var TicketSchema = new mongoose.Schema({
title: String,
description: String
}, {versionKey: false});
module.exports = mongoose.model('Ticket', TicketSchema, 'Ticket');
routes/ticket.js
var Ticket = require('../models/ticket');
module.exports = function(app){
_getAllTickets = function(req, res){
var query = Ticket.find().lean();
query.exec(function(err, lst){
if(err)
res.send(err);
res.json(lst);
});
};
_saveTicket = function(req, res){
console.log(req.body);
var tckt = new Ticket({
title: req.body.title,
description: req.body.description
});
tckt.save(function(err){
if(!err)
console.log('Ticket creation successful. ');
else
console.log('ERROR: ' + err);
});
res.send(tckt);
};
app.get('/api/tickets/', _getAllTickets);
app.post('/api/tickets/', _saveTicket);
}
Make sure that the HTTP request has the Content-Type header set to be application/json or x-www-form-urlencoded based on your body-parser middleware definitions. My guess is that its coming through right now as neither of those Content-Type's

How do I get emoticons working in express? [duplicate]

I am trying to create a POST with an emoji to my Express endpoint:
curl --data '{"x": 10, "y":10, "z":10, "message": "😋", "userToken": "Marine"}' --header "Content-Type:application/json" localhost:3000/api/messages
For some reason this crashes my server:
SyntaxError: Unexpected token
at Object.parse (native)
at parse (/Users/user/Documents/uncovery/node_modules/body-parser/lib/types/json.js:84:17)
at /Users/user/Documents/uncovery/node_modules/body-parser/lib/read.js:102:18
at IncomingMessage.onEnd (/Users/user/Documents/uncovery/node_modules/body-parser/node_modules/raw-body/index.js:149:7)
at IncomingMessage.g (events.js:199:16)
at IncomingMessage.emit (events.js:104:17)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
I went to my router and put console.log's in my /messages endpoint to see what is being received but when Express crashes as a result of sending an emoji the console.log is never activated.
router.js
var models = require('../db/models.js');
var util = require('../core/utilities.js');
var sockets = require('../routes/sockets.js');
module.exports = function(router) {
//input: {x: float, y: float, z: float, message: string, userToken: string}
router.post('/messages', function(req, res) {
console.log("Emoji: ", req.body);
models.createMessage(req.body).then(
util.resolvePOST.bind(this, req, res),
util.rejectPOST.bind(this, req, res)
);
});
}
I suspect this has something to do with the middleware and not actually related to the routes, but when I google emojis crash node js I can't find anything relevant. Why is this happening?
index.js
var http = require('http');
var morgan = require('morgan');
var express = require('express');
var socketIO = require('socket.io');
var bodyParser = require('body-parser');
var util = require('./server/core/utilities.js');
var router = require('./server/routes/router.js');
var sockets = require('./server/routes/sockets.js');
var app = express();
var server = http.Server(app);
app.use(morgan('combined', util.getLogStream()));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json({ limit: '50mb' }));
app.use('/api', router);
app.use(express.static(__dirname + '/server/landing'));
var io = socketIO(server);
sockets.initialize(io);
server.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Uncovery listening at http://%s:%s', host, port);
});

Categories

Resources