'username: req.body.username' username in last of line is undefined - node.js

Hello I am creating login-register system in my project, actually I made it in many of my previous projects but this time I am getting an error, for which I've seen many posts related to this but none of them worked for me.
I got some issues on "verifySignUp.js" that
"TypeError: Cannot read property 'username' of undefined"
on last 'undefined' of line 'username: req.body.username'
and This is my postman data push
{
"username":"deayhrovv",
"email":"deayhrovv#gmail.com",
"password":"123456",
"roles":["user","moderater"]
}
this is my server.js
var express = require("express");
var bodyParser = require("body-parser");
var cors = require("cors");
var dbConfig = require("./app/config/db.config");
var db = require("./app/models");
var Role = db.role;
var app = express();
// routes
require('./app/routes/auth.routes')(app);
require('./app/routes/user.routes')(app);
var corsOptions = {
origin: "http://localhost:8080"
};
db.mongoose
.connect(`mongodb://${dbConfig.HOST}:${dbConfig.PORT}/${dbConfig.DB}`, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Successfully connect to MongoDB.");
initial();
})
.catch(err => {
console.error("Connection error", err);
process.exit();
});
function initial() {
Role.estimatedDocumentCount((err, count) => {
if (!err && count === 0) {
new Role({
name: "user"
}).save(err => {
if (err) {
console.log("error", err);
}
console.log("added 'user' to roles collection");
});
new Role({
name: "moderator"
}).save(err => {
if (err) {
console.log("error", err);
}
console.log("added 'moderator' to roles collection");
});
new Role({
name: "admin"
}).save(err => {
if (err) {
console.log("error", err);
}
console.log("added 'admin' to roles collection");
});
}
});
}
app.use(cors(corsOptions));
// parse requests of content-type - application/json
app.use(bodyParser.json())
// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// simple route
app.get("/", (req, res) => {
res.json({ message: "Welcome to Canteen Food Order APIs application ."});
});
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on url ${corsOptions.origin}.`);
});
This is my middlewares
const { verifySignUp } = require("../middlewares");
const controller = require("../controllers/auth.controller");
module.exports = function(app) {
app.use(function(req, res, next) {
res.header(
"Access-Control-Allow-Headers",
"x-access-token, Origin, Content-Type, Accept"
);
next();
});
app.post(
"/api/auth/signup",
[
verifySignUp.checkDuplicateUsernameOrEmail,
verifySignUp.checkRolesExisted
],
controller.signup
);
app.post("/api/auth/signin", controller.signin);
};
This is my verifySignUp.js
const db = require("../models");
const ROLES = db.ROLES;
const User = db.user;
checkDuplicateUsernameOrEmail = (req, res, next) => {
User.findOne()
// Username
User.findOne({
username: req.body.username
}).exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}
if (user) {
res.status(400).send({ message: "Failed! Username is already in use!" });
return;
}
// Email
User.findOne({
email: req.body.email
}).exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}
if (user) {
res.status(400).send({ message: "Failed! Email is already in use!" });
return;
}
next();
});
});
};
checkRolesExisted = (req, res, next) => {
if (req.body.roles) {
for (let i = 0; i < req.body.roles.length; i++) {
if (!ROLES.includes(req.body.roles[i])) {
res.status(400).send({
message: `Failed! Role ${req.body.roles[i]} does not exist!`
});
return;
}
}
}
next();
};
const verifySignUp = {
checkDuplicateUsernameOrEmail,
checkRolesExisted
};
module.exports = verifySignUp;

Incase of GET request, you need to access the parameters using req.query instead of req.body. So, modify the simple route to following
app.get("/", (req, res) => {
Username = req.query.username
res.json({ message: "Welcome to Canteen Food Order APIs application ." + Username });
});

Related

Client doesnt get cookie from my node.js api

I have made an authentication with jwt api in node.js/express and i run it on heroku.
When a user logged in, server create a cookie via cookie-parser and send it to the client.
Below is the code from server.js
const express = require('express');
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const cors = require('cors');
const path = require('path');
const bcrypt = require('bcrypt');
const PORT = process.env.PORT || 3000;
const serveStatic = require('serve-static');
require('dotenv').config();
const mongoose = require('mongoose');
const { User, Posts } = require(path.join(__dirname, './model.js'));
const mongoString = process.env.DATABASE_URL;
const JWT_SECRET = process.env.JWT_SECRET;
const { verifyToken, checkUser } = require(path.join(__dirname, './auth.js'));
const app = express();
//Middlewares
app.use(
cors({
credentials: true,
origin: true,
})
);
app.use(express.json());
app.use(cookieParser());
//Connect to Database
mongoose.connect(mongoString);
const db = mongoose.connection;
db.on('error', (err) => {
console.log(err);
});
db.once('connected', () => {
console.log('----Database Connected----\n');
});
//functions
const maxAge = 3 * 24 * 60 * 60;
const createToken = (id) => {
return jwt.sign({ id }, JWT_SECRET, {
expiresIn: maxAge,
});
};
// AUTH ROUTES
app.get('*', checkUser);
app.get('/', checkUser, (req, res) => {
res.json({ status: 'success' });
});
app.post('/api/register', async (req, res) => {
const salt = await bcrypt.genSalt();
try {
const user = await User.create(
new User({
username: req.body.username,
email: req.body.email,
city: req.body.city,
password: await bcrypt.hash(req.body.password, salt),
})
);
const token = createToken(user._id);
res.cookie('jwt', token, {
maxAge: maxAge * 1000,
secure: true,
});
res.status(201).json(user);
console.log(user);
} catch (err) {
console.log(err);
res.json(err);
}
});
app.post('/api/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email }).lean();
if (!user) {
return res.send({
status: 'error',
error: 'Invalid email',
});
}
if (await bcrypt.compare(password, user.password)) {
const token = createToken(user._id);
res.cookie('jwt', token, { secure: true, maxAge: maxAge * 1000 });
res.status(200).send({ status: 'ok', token: token });
console.log(user._id + ' logged in successfully');
return;
}
return res.send({ status: 'error', error: 'Invalid password' });
} catch (err) {
console.log(err);
}
});
app.get('/api/home', verifyToken, (req, res) => {
res.send(res.locals.user);
});
app.get('/api/logout', (req, res) => {
try {
res.cookie('jwt', '', { maxAge: 1 });
res.status(200).send({ status: 'ok' });
} catch (err) {
res.send(err);
}
});
//POSTS ROUTES
app.post('/api/posts', verifyToken, checkUser, async (req, res) => {
try {
const post = await Posts.create(
new Posts({
postBody: req.body.postBody,
city: req.body.city,
author: res.locals.user.id,
})
);
res.status(200).json(post);
console.log('====New Post=====');
} catch (err) {
res.status(400).send({ message: err.message });
}
});
app.get('/api/posts', verifyToken, async (req, res) => {
try {
const data = await Posts.find();
res.send({ user: res.locals.user, data: data });
} catch (err) {
res.json({ message: err.message });
}
});
app.get('/api/posts/:city', verifyToken, async (req, res) => {
try {
const data = await Posts.find({ city: req.params.city });
res.json(data);
res.send(res.locals.user);
} catch (err) {
res.json({ message: err.message });
}
});
//run server
app.listen(PORT, () => {
console.log(`Server running on ${PORT}...\n`);
});
Now, for front-end i use Vue.js that its running on Firebase.
Here is the script part of Login.Vue
<script>
/* eslint-disable */
import axios from 'axios';
export default {
name: 'Login',
data() {
return {
email: '',
password: '',
error: '',
};
},
methods: {
async onSubmit() {
if (!this.email || this.password.length < 6) {
this.error = 'vale kati';
return;
}
await axios
.post(
'https://thelostpet.herokuapp.com/api/login',
{
email: this.email,
password: this.password,
},
{ withCredentials: true }
)
.then((res) => {
console.log(res.data.token);
if (res.data.status == 'error') {
this.error = res.data.error;
}
if (res.data.status == 'ok') {
this.$router.push('/home');
}
})
.catch((err) => {
console.log(err);
});
},
},
};
</script>
When I try to login from Login.vue, that its ruuning on Firebase, the browser doesn't save the cookie that it created from the api.
BUT when I make a post request on https://thelostpet.herokuapp.com/api/login from postman, the cookie is saved on postman.
Thank you!

I am getting 404 error and 204 error when consuming backend (node,vuejs)?

When signing in with postman everything works fine. But when i am doing an axios request i get 404 error and directly after 204 error. When i render my vue.js page i get "cannot get api/auth/signin. Also I get a message somewhere that says user not found.
What i have tried:
Frontend: I tried with adding headers to my axios request. I console logged the data and it seems perfectly fine.
Backend: Changed deprecated body parsers.
Frontend Code:
Auth store
import axios from "axios";
const state = {
token: "",
users: [],
};
const getters = {};
const actions = {
async signIn(_, payload) {
const response = await axios.post(
"http://localhost:3000/api/auth/signin",
{ payload },
{
headers: {
"Content-Type": "application/json",
},
}
);
console.log(response.data);
console.log(response.headers);
console.log(response.status);
},
};
const mutations = {};
export default {
state,
getters,
actions,
mutations,
};
This is my backend:
Controller
//signin
exports.signin = (req, res) => {
User.findOne({
username: req.body.username,
})
.populate("roles", "-__v")
.exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}
if (!user) {
return res.status(404).send({ message: "User Not found." });
}
var passwordIsValid = bcrypt.compareSync(
req.body.password,
user.password
);
if (!passwordIsValid) {
return res.status(401).send({
accessToken: null,
message: "Invalid Password!",
});
}
var token = jwt.sign({ id: user.id }, config.secret, {
expiresIn: 86400, // 24 hours
});
var authorities = [];
for (let i = 0; i < user.roles.length; i++) {
authorities.push("ROLE_" + user.roles[i].name.toUpperCase());
}
res.status(200).send({
id: user._id,
username: user.username,
email: user.email,
roles: authorities,
accessToken: token,
});
});
};
Route
module.exports = function (app) {
app.use(function (req, res, next) {
res.header(
"Access-Control-Allow-Headers",
"x-access-token, Origin, Content-Type, Accept"
);
next();
});
app.post(
"/api/auth/signup",
[
verifySignUp.checkDuplicateUsernameOrEmail,
verifySignUp.checkRolesExisted,
],
controller.signup
);
app.post("/api/auth/signin", controller.signin);
And my server
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const jwt = require("jsonwebtoken");
const mongoose = require("mongoose");
const Quote = require("./models/Quote");
const quoteRoute = require("./routes/quoteRoute");
const quoteController = require("../Maxico/controllers/quoteController");
const config = require("./config/config");
const verifySignup = require("./middlewares/verifySignUp");
const Role = require("./models/Role");
const app = express();
//Import routes
//const authRoute = require("./routes/auth");
var corsOptions = {
origin: "http://localhost:8080/?#/",
};
app.use(cors(corsOptions));
app.use(express.urlencoded({ extended: true }));
app.use(express.json()); //
const db = require("./models/Quote");
mongoose
.connect(
"url",
{
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
}
)
.then(() => {
console.log("Connected to the database!");
})
.catch((err) => {
console.log("Cannot connect to the database!", err);
process.exit();
});
app.use(express.json());
app.get("/", (req, res) => {
res.send("Welcome to homepage");
});
app.use("/quote", quoteRoute);
require("./routes/authRoute")(app);
//require("./routes/userRoute")(app);
// initial roles
Role.estimatedDocumentCount((err, count) => {
if (!err && count === 0) {
new Role({
name: "user",
}).save((err) => {
if (err) {
console.log("error", err);
}
console.log("added 'user' to roles collection");
});
new Role({
name: "moderator",
}).save((err) => {
if (err) {
console.log("error", err);
}
console.log("added 'moderator' to roles collection");
});
new Role({
name: "admin",
}).save((err) => {
if (err) {
console.log("error", err);
}
console.log("added 'admin' to roles collection");
});
new Role({
name: "superadmin",
}).save((err) => {
if (err) {
console.log("error", err);
}
console.log("added 'superadmin' to roles collection");
});
}
});
// set port, listen for requests
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
In my network tab the request pay load got sent like this:
{payload: {username: "jon", password: "password"}}
payload: {username: "jon", password: "password"}
But my postman only accepts this:
{username: "jon", password: "password"}
So in my action i sent like this:
const actions = {
async signIn(_, payload) {
console.log(payload);
const response = await axios.post(
"http://localhost:3000/api/auth/signin",
payload,
{
headers: {
"Content-Type": "application/json",
},
}
);
console.log(payload);
console.log(response.data);
console.log(response.headers);
console.log(response.status);
},
};

PUT method not allowed with http-proxy

When calling my PUT method, I got this error:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body>
</html>
I have some jwt authentification, so I put my complete code here:
It works with GET and POST methods
const express = require('express');
const logger = require('morgan');
var fs = require('fs');
var https = require('https');
var privateKey = fs.readFileSync('/etc/letsencrypt/live/hidden/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/hidden/fullchain.pem', 'utf8');
const util = require('util')
var credentials = {key: privateKey, cert: certificate};
var queryString = require('querystring');
const bodyParser = require('body-parser');
const app = express();
const jwt = require('jsonwebtoken');
// import passport and passport-jwt modules
const passport = require('passport');
const passportJWT = require('passport-jwt');
const bcrypt = require('bcryptjs');
const Sequelize = require('sequelize');
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var backend = 'http://localhost:8484';
// initialize an instance of Sequelize
const sequelize = new Sequelize({
//hiden///
});
// ExtractJwt to help extract the token
let ExtractJwt = passportJWT.ExtractJwt;
// JwtStrategy which is the strategy for the authentication
let JwtStrategy = passportJWT.Strategy;
let jwtOptions = {};
jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
jwtOptions.secretOrKey = 'hidden';
// lets create our strategy for web token
let strategy = new JwtStrategy(jwtOptions, function(jwt_payload, next) {
console.log('payload received', jwt_payload);
let user = getUser({ id: jwt_payload.id });
if (user) {
next(null, user);
} else {
next(null, false);
}
});
// use the strategy
passport.use(strategy);
app.use(passport.initialize());
app.use(logger(':date[iso] :method :url :status :response-time ms - :res[content-length]'));
// parse application/json
app.use(bodyParser.json());
//parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// check the databse connection
sequelize
.authenticate()
.then(() => console.log('Connection has been established successfully.'))
.catch(err => console.error('Unable to connect to the database:', err));
// create user model
const User = sequelize.define('user', {
name: {
type: Sequelize.STRING,
allowNull: false
},
code_event: {
type: Sequelize.INTEGER,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
},
});
// create table with user model
User.sync()
.then(() => console.log('User table created successfully'))
.catch(err => console.log('did you enter wrong database credentials?'));
// create some helper functions to work on the database
const createUser = async ({ name, password, code_event }) => {
try{
return await User.create({ name, password, code_event });
}
catch (error) {
// your catch block code goes here
}
};
const getAllUsers = async () => {
try{
return await User.findAll();
}
catch (error) {
// your catch block code goes here
}
};
const getUser = async obj => {
try{
return await User.findOne({where: obj,});
}
catch (error) {
// your catch block code goes here
}
};
// get all users
app.get('/users', function(req, res) {
getAllUsers().then(user => res.json(user));
});
// register route
app.post('/register', function(req, res, next) {
console.log(req.body);
let { name, password, code_event } = req.body;
bcrypt.genSalt(10, (err, salt) => {
if(err) throw err;
bcrypt.hash(password, salt,
(err, hash) => {
if(err) throw err;
password = hash;
createUser({ name, password, code_event }).then(user =>
res.json({ user, msg: 'account created successfully' })
)
.catch(err => res.status(400).json(err));
});
});
});
// login route
app.post('/login', async function(req, res, next) {
console.log(req.body);
const { name, password , code_event} = req.body;
if (name && password) {
// we get the user with the name and save the resolved promise returned
let user = await getUser({ name, code_event});
if (!user) {
res.status(401).json({ msg: 'No such user found', user });
}
bcrypt.compare(password, user.password)
.then(isMatch => {
if (isMatch) {
const payload = {id: user._id};
// let token = jwt.sign(payload, jwtOptions.secretOrKey, { expiresIn: 36000 }, (err, token) => {
// if (err) res.status(500).json({ error: "Error signing token", raw: err });
// res.json({ msg: 'ok', token: token });
// });
let token = jwt.sign(payload, jwtOptions.secretOrKey);
res.json({ msg: 'ok', token: token });
} else {
res.status(401).json("Password is incorrect");
}
});
}
});
apiProxy.on( 'proxyReq', ( proxyReq, req, res, options ) => {
console.log("body " +util.inspect(req.body, false, null, true /* enable colors */));
if ( !req.body || !Object.keys( req.body ).length ) {
return;
}
let contentType = proxyReq.getHeader( 'Content-Type' );
let bodyData;
if ( contentType.includes( 'application/json' ) ) {
bodyData = JSON.stringify( req.body );
}
if ( contentType.includes( 'application/x-www-form-urlencoded' ) ) {
bodyData = queryString.stringify( req.body );
}
if ( bodyData ) {
proxyReq.setHeader( 'Content-Length', Buffer.byteLength( bodyData ) );
proxyReq.write( bodyData );
}
});
app.all("/*", passport.authenticate('jwt', { session: false }), function(req, res) {
console.log("req all" + req);
apiProxy.web(req, res, {target: backend});
});
app.on('upgrade', function (req, socket, head) {
console.log("req on" + req);
apiProxy.ws(req, socket, head, {target: backend});
});
var httpsServer = https.createServer(credentials, app);
// start the app
httpsServer.listen(8383, function() {
console.log("Express is running on port 3000");
});
It works with my POST methods.
I don't know where it goes because, when calling a method, I should have a trace in my log files. I can see POST ot GET calls but not PUT ones.
Any ideas?

Error: Can't set headers after they are sent.

Error: Can't set headers after they are sent. I hate this problem because get it many times and I though that I found my mistake,but I was wrong.
Okay this my code.
const mongoose = require ("mongoose");
const Spec = require("./specialist");
const Person = require("./person");
const Company = require("./company");
const bcrypt = require("bcryptjs");
module.exports.findUser=function(username,callback){
let query = {email_num:username};
Spec.findOne(query,(err_spec,spec_user)=>{
if(err_spec) throw err_spec;
if(!spec_user){
Person.findOne(query,(err_person,person_user)=>{
if(err_person) throw err_person;
if(!person_user){
Company.findOne(query,(err_company,company_user)=>{
if(err_company) throw err_company;
if(!company_user){
return console.log("Error User Not Found");
}
return callback(null,company_user);
});
}
return callback(null,person_user);
});
}
return callback(null,spec_user);
});
};
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, (err, isMatch) => {
if(err) throw err;
callback(null, isMatch);
});
};
module.exports.saveToken = function(username,role,token,callback){
let query = {email_num:username};
let updateToken={updatedToken:token};
if(role==="Person-User"){
Person.findOneAndUpdate(query,updateToken,callback);
}else if(role==="Specialist-User"){
Spec.findOneAndUpdate(query,updateToken,callback);
}else if(role==="Company-User"){
Company.findOneAndUpdate(query,updateToken,callback);
}else{
console.log("Something went goes wrong");
}
}
I've created 3 collections and this file for handling them all.
This is my main server code.
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
const handlebars = require("express-handlebars");
const app = express();
const passport = require('passport');
const cookieParser = require("cookie-parser");
const config = require("./config/data");
const routes = require("./routes/users");
const company = require("./routes/company");
const person = require("./routes/person");
mongoose.Promise = global.Promise;
let options = {
useMongoClient: true,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 500,
poolSize: 10,
bufferMaxEntries: 0
};
mongoose.connect(config.database,options);
let db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log( `DB connected ${new Date()}...`);
});
//app.set('views',__dirname+'views');
app.engine('handlebars', handlebars({defaultLayout:false}));
app.set('view engine', 'handlebars');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(__dirname + '/public'));
// app.use(cors());
app.use(cookieParser());
// Passport Middleware
// require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
app.get("/",(req,res)=>{
res.render("index");
});
// app.get("/forgotPass",(req,res)=>{
// res.render("forgotPass");
// });
app.get("/user", (req,res)=>{
res.render("user");
});
app.get("/login",(req,res)=>{
res.render("login");
});
app.get("/signup",(req,res)=>{
res.render("signup");
});
app.get("/we",(req,res)=>{
res.render("we");
});
app.get("/blog",(req,res)=>{
res.render("blog");
});
app.get("/contactUs",(req,res)=>{
res.render("contactUs");
});
app.get("/userAsApplicant",(req,res)=>{
res.render("userAsApplicant");
});
app.use("/users",routes);
app.use("/company",company);
app.use("/person",person);
app.get("/faq",(req,res)=>{
res.render("faq");
});
app.listen(config.port,()=>{
console.log(`Server running on port ${config.port}....`);
});
Also for many form handler I'm using Ajax for all requests.
$(function () {
$('.subForm').on('submit', function (e) {
$.ajax({
type: 'post',
url: 'http://localhost:3000/users/spec/register',
data: $(this).serialize(),
success:function(data){
if(data.success){
location.href="http://localhost:3000/login"
}else{
location.href="http://localhost:3000/signup"
}
}
});
e.preventDefault();
});
$('.personAuth').on('submit', function (e) {
$.ajax({
type: 'post',
url: 'http://localhost:3000/person/register',
data: $(this).serialize(),
success:function(data){
if(data.success){
location.href="http://localhost:3000/login"
}else{
console.log("Chexav");
location.href="http://localhost:3000/signup";
}
}
});
e.preventDefault();
});
$('.companyAuth').on('submit', function (e) {
$.ajax({
type: 'post',
url: 'http://localhost:3000/company/register',
data: $(this).serialize(),
success:function(data){
if(data.success){
location.href="http://localhost:3000/login"
}else{
location.href="http://localhost:3000/signup"
}
}
});
e.preventDefault();
});
$('.logInForm').on('submit', function (e) {
$.ajax({
type: 'post',
url: 'http://localhost:3000/users/authenticate',
data: $(this).serialize(),
success:function(data){
console.log(data);
if(data.token){
localStorage.setItem("Authorization",data.token);
$.ajax({
type:'get',
url:'http://localhost:3000/users/user',
beforeSend: function(xhr){xhr.setRequestHeader('auth', localStorage.getItem("Authorization"));},
success:location.href="http://localhost:3000/users/user"
})
}
}
});
e.preventDefault();
});
});
And this route for authentication.
const express = require("express");
const router = express.Router();
const Spec = require("../models/specialist");
const jwt = require("jsonwebtoken");
const config = require("../config/data");
const Model = require("../models/model");
//Registration route
router.post("/spec/register",(req,res)=>{
let date=new Date();
let newUser = new Spec({
name:req.body.spec_name,
email_num:req.body.spec_email,
password:req.body.spec_password,
role:"Specialist-User",
isActive:true,
created:date,
updatedToken:"JWT"
});
if(newUser.password===req.body.spec_confirmPass){
Spec.getUser(newUser.email_num,(error,user)=>{
if(error) throw error;
if(!user){
Spec.addUser(newUser,(err,user)=>{
if(err){
console.log("err");
res.json({success:false,msg:"Somethings Went Wrong"});
} else {
res.header("Content-Type","application/json");
res.json({success:true,msg:"User Registered"});
// res.redirect("/login");
}
});
}else{
res.json({success:false,msg:"User Already Exists"});
}
});
}else{
res.json({success:false,msg:"Password Not Confirmed"});
}
});
//Authentication route
router.post('/authenticate', (req, res,next) => {
const email = req.body.email;
const password = req.body.password;
console.log("UserData");
Model.findUser(email, (err, user) => {
console.log("UserData1");
if(err) throw err;
if(!user){
return res.json({success: false, msg: 'User not found'});
}
Model.comparePassword(password, user.password, (err, isMatch) => {
console.log("UserData2");
if(err) throw err;
if(isMatch){
let payload={
name:user.name,
email:user.email_num,
role:user.role,
deleted:user.deleted,
isActive:user.isActive,
created:user.created,
};
let token = jwt.sign(payload,config.JWT_SECRET,{
expiresIn:1440
});
Model.saveToken(email,user.role,token,(err,success)=>{
if(err) return err;
console.log("Success");
// res.setHeader('Authorization',token);
// res.cookie('Authorization',token);
res.json ({ success: true, token: token });
// res.redirect("/users/user");
});
} else {
return res.json({success: false, msg: 'Wrong password'});
}
});
});
// res.redirect("/user");
});
router.use(function(req, res, next) {
console.log(req.headers);
let token = req.body.token || req.headers['auth'] || req.query.token || req.cookies.Authorization;
// console.log(token);
if (token) {
jwt.verify(token, config.JWT_SECRET, function(err, decoded) {
if (err) {
console.log(err);
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
req.decoded = decoded;
next();
res.render("user");
}
});
} else {
return res.status(403).json({
success: false,
message: 'No token provided.'
});
}
});
router.get("/user", (req,res)=>{
res.render("user");
});
module.exports = router;
As template engine I'm using Handlebars.So with registration everything okay,but when I'm trying to authenticate server brings
Error: Can't set headers after they are sent.
I know that I can use cookies,but I want to keep away from that.
Sorry for language mistakes, and Thanks for help.
Error: Can't set headers after they are sent.
It means that you are sending multiple response to your client side.
I think you just need to delete your res.render("user"); in your last middleware like this :
router.use(function(req, res, next) {
console.log(req.headers);
let token = req.body.token || req.headers['auth'] || req.query.token || req.cookies.Authorization;
// console.log(token);
if (token) {
jwt.verify(token, config.JWT_SECRET, function(err, decoded) {
if (err) {
console.log(err);
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
req.decoded = decoded;
// Go next and delete res
next();
// res.render("user");
}
});
} else {
return res.status(403).json({
success: false,
message: 'No token provided.'
});
}
});
Hope it helps.

CANNOT GET with mongodb and nodejs

hello i'm trying to GET a book by his name from my db but when i execute the script the localhost shuts down and i have to restart. also i get the error :
ReferenceError: text is not defined
here is the server.js
var express = require('express');
MongoClient = require('mongodb').MongoClient,
app = express(),
mongoUrl = 'mongodb://localhost:27017/firstapp';
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var passport = require('passport');
var redisClient = require('redis').createClient;
var redis = redisClient(6379, 'localhost');
var config = require('./config/database'); // get db config file
var User = require('./app/models/user'); // get the mongoose model
var Products = require('./app/models/products'); //get the mongoose model
var Makeissue = require('./app/models/makeissue'); //get the mongoose model
var port = process.env.PORT || 8080;
var jwt = require('jwt-simple');
var access = require('./config/database.js');
MongoClient.connect(mongoUrl, function(err, db) {
if (err) throw 'Error connecting to database - ' + err;
// get our request parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// log to console
app.use(morgan('dev'));
// Use the passport package in our application
app.use(passport.initialize());
// demo Route (GET http://localhost:8080)
app.get('/', function(req, res) {
res.send('The API is at http://localhost:' + port + '/api');
});
// connect to database
mongoose.connect(config.database);
// pass passport for configuration
require('./config/passport')(passport);
// bundle our routes
var apiRoutes = express.Router();
// create a new user account (POST http://localhost:8080/api/signup)
apiRoutes.post('/signup', function(req, res) {
if (!req.body.name || !req.body.password || !req.body.email) {
res.json({success: false, msg: 'Please pass name and password and email.'});
} else {
var newUser = new User({
name: req.body.name,
password: req.body.password,
email: req.body.email
});
// save the user
newUser.save(function(err) {
if (err) {
return res.json({success: false, msg: 'Username already exists.'});
}
res.json({success: true, msg: 'Successful created new user.'});
});
}
});
// route to authenticate a user (POST http://localhost:8080/api/authenticate)
apiRoutes.post('/authenticate', function(req, res) {
User.findOne({
name: req.body.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.send({success: false, msg: 'Authentication failed. User not found.'});
} else {
// check if password matches
user.comparePassword(req.body.password, function (err, isMatch) {
if (isMatch && !err) {
// if user is found and password is right create a token
var token = jwt.encode(user, config.secret);
// return the information including token as JSON
res.json({success: true, token: 'JWT ' + token});
} else {
res.send({success: false, msg: 'Authentication failed. Wrong password.'});
}
});
}
});
});
apiRoutes.post('/book', function (req, res) {
if (!req.body.title || !req.body.author) res.status(400).send("Please send a title and an author for the book");
else if (!req.body.text) res.status(400).send("Please send some text for the book");
else {
access.saveBook(db, req.body.title, req.body.author, req.body.text, function (err) {
if (err) res.status(500).send("Server error");
else res.status(201).send("Saved");
});
}
});
apiRoutes.get('/book/:title', function (req, res) {
if (!req.param('title')) res.status(400).send("Please send a proper title");
else {
access.findBookByTitle(db, req.param('title'), function (book) {
if (!text) res.status(500).send("Server error");
else res.status(200).send(book);
});
}
});
// create a new Product (POST http://localhost:8080/api/productsignup)
apiRoutes.post('/resources/productsignup', function(req, res) {
if (!req.body.name || !req.body.serialnumber) {
res.json({success: false, msg: 'Please pass name and serial number.'});
} else {
var newProducts = new Products({
name: req.body.name,
serialnumber: req.body.serialnumber
});
// save the Product
newProducts.save(function(err) {
if (err) {
return res.json({success: false, msg: 'Product already exists.'});
}
res.json({success: true, msg: 'Successful created new Product.'});
});
}
});
apiRoutes.post('/resources/createpost', function(req, res) {
if (!req.body.issue) {
res.json({success: false, msg: 'Please pass a issue.'});
} else {
var newMakeissue = new Makeissue({
issue: req.body.issue
});
// save the Product
newMakeissue.save(function(err) {
if (err) {
return res.json({success: false, msg: 'Post already exists.'});
}
res.json({success: true, msg: 'Successful created new post.'});
});
}
});
//display a specific product stored in database
apiRoutes.get('/resources/productinfo/:name' , function(req, res) {
if (!req.param('name')) res.status(400).send("Please send a proper name");
else{
Products.find(Products, req.param('name'), function(Products) {
if (!text) res.status(500).send("server error");
});
}
});
apiRoutes.get('/productinfo' , function(req, res, next) {
Products.find( function (err, result) {
if (err) return console.error(err);
res.json(result);
});
});
// route to a restricted info (GET http://localhost:8080/api/memberinfo)
apiRoutes.get('/memberinfo', passport.authenticate('jwt', { session: false}), function(req, res) {
var token = getToken(req.headers);
if (token) {
var decoded = jwt.decode(token, config.secret);
User.findOne({
name: decoded.name
}, function(err, user) {
if (err) throw err;
if (!user) {
return res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
} else {
res.json({success: true, msg: 'Welcome in the member area ' + user.name + '!'});
}
});
} else {
return res.status(403).send({success: false, msg: 'No token provided.'});
}
});
getToken = function (headers) {
if (headers && headers.authorization) {
var parted = headers.authorization.split(' ');
if (parted.length === 2) {
return parted[1];
} else {
return null;
}
} else {
return null;
}
};
// connect the api routes under /api/*
app.use('/api', apiRoutes);
module.exports = apiRoutes;
app.listen(8080, function() {
console.log('listening on port 8080');
});
});
and the database.js
module.exports = {
'secret': 'di.ionio.gr',
'database': 'mongodb://localhost/firstapp'
};
module.exports.saveBook = function (db, title, author, text, callback) {
db.collection('text').save({
title: title,
author: author,
text: text
}, callback);
};
module.exports.findBookByTitle = function (db, title, callback) {
db.collection('text').findOne({
title: title
}, function (err, doc) {
if (err || !doc) callback(null);
else callback(doc.text);
});
};
What am i doing wrong?
not sure if there are other issues with the code. but with the error ReferenceError: text is not defined, might the compiler be complaining that they cannot determine where text was declared in the following lines?
apiRoutes.get('/book/:title', function (req, res) {
...
if (!text) res.status(500).send("Server error");
...
apiRoutes.get('/resources/productinfo/:name' , function(req, res) {
...
if (!text) res.status(500).send("server error");
...
if that is the error, you might need to replace text with req.body.text

Resources