Cannot read properties node.js - javascript

I've got a problem, I wrote a code which should update my user in a db but when I try to do it in Postman I get an information that the programme can't read my property token. Could somebody help me?
My verifytoken.js code
const { response } = require('express');
const jwt = require('jsonwebtoken');
const verifyToken = (req, res, next) => {
const authHeader = res.headers.token;
if(authHeader){
const token = authHeader.split(' ')[1];
jwt.verify(token, process.env.JWT_SEC, (err, user) => {
if(err) res.status(403).json("Token isn't valid");
req.user = user;
next();
})
}else{
return res.status(401).json("You are not authenticated");
}
}
const verifytokenandauth = (req, res, next) => {
verifyToken(req, res, ()=>{
if(req.user.id=== req.params.id || req.user.admin) {
next();
}else{
res.status(403).json("You are not allowed to do this");
}
})
}
module.exports = {verifyToken, verifytokenandauth}
My user.js code
const { verifytokenandauth } = require('./verifytoken');
const {User} = require('../models/user');
const router = require('express').Router();
router.put('/:id', verifytokenandauth, async (req, res) => {
if(req.body.password){
req.body.password = CryptoJs.AES.encrypt(req.body.password, process.env.PASS_SEC).toString()
}
try{
const updateduser = await User.findByIdAndUpdate(req.User.id, {
$set: req.body
},{new: true});
res.status(200).json(updateduser);
}catch(err) {res.status(500).json(err);}
});
module.exports = router
And screenshot from Postman
Thanks in advance :)

Related

I have faced CORS policy error .No 'Access-Control-Allow-Origin' header is present on the requested resource [duplicate]

This question already has answers here:
How to enable cors nodejs with express?
(10 answers)
Closed 10 months ago.
I have faced this problem so many time. I require all the middleware in my backend server code but it good for sometimes and then occur, after sometimes it's again running on his own and again cors policy error occur. Please give me a solution . Here is my backend code...
const express = require("express");
const { MongoClient, ServerApiVersion, ObjectId } = require("mongodb");
const cors = require("cors");
const jwt = require("jsonwebtoken");
const port = process.env.PORT || 5000;
require("dotenv").config();
const app = express();
//necessary middleware app.use(cors()); app.use(express.json());
function verifyJWT(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader) {
return res.status(401).send({ message: "unauthorized access" });
}
const token = authHeader.split(" ")[1];
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, decoded) => {
if (err) {
return res.status(403).send({ message: "Forbidden access" });
}
console.log("decoded", decoded);
req.decoded = decoded;
next();
});
}
const uri = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}#cluster0.nfrv0.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
console.log(uri);
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
serverApi: ServerApiVersion.v1,
});
async function run() {
try {
await client.connect();
const fruitCollection = client.db("fruitsInventory").collection("fruit");
//AUTH API
app.post("/login", async (req, res) => {
const user = req.body;
const accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: "1d",
});
res.send({ accessToken });
});
//get data
app.get("/inventory", async (req, res) => {
const query = {};
const cursor = fruitCollection.find(query);
const result = await cursor.toArray();
res.send(result);
});
//get inventory id
app.get("/inventory/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await fruitCollection.findOne(query);
res.send(result);
});
//get api with filter email
app.get("/myitem", verifyJWT, async (req, res) => {
const decodeEmail = req.decoded.email;
const email = req.query.email;
if (email === decodeEmail) {
const query = { email: email };
const cursor = fruitCollection.find(query);
const result = await cursor.toArray();
res.send(result);
} else {
res.status(403).send({ message: "Forbidden Access" });
}
});
//delete api
app.delete("/myitem/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await fruitCollection.deleteOne(query);
res.send(result);
});
//post data
app.post("/inventory", async (req, res) => {
const newItem = req.body;
const result = await fruitCollection.insertOne(newItem);
res.send(result);
});
//update data for quantity
app.put("/inventory/:id", async (req, res) => {
const id = req.params.id;
const updateQuantity = req.body;
const filter = { _id: ObjectId(id) };
const options = { upsert: true };
const updateDoc = {
$set: {
quantity: updateQuantity.quantity,
},
};
const result = await fruitCollection.updateOne(
filter,
updateDoc,
options
);
res.send(result);
});
//delete item
app.delete("/inventory/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await fruitCollection.deleteOne(query);
res.send(result);
});
} finally {
}
}
run().catch(console.dir);
app.get("/", (req, res) => {
res.send("fruits server is running");
});
app.listen(port, () => {
console.log("server is connected on port", port);
});
You must set the header of the Axios first because CORS means that you don't have access to origin resource API, so you need to setup the header of Axios first, you can follow this resource CORS
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})

my template engine file not rendered in my router file

hello every one in this code i have a template engine file but not rendered and i havent a error
and i cant see it
i need a help in /admin/article/new
this is my module code
const express = require('express');
const router = express.Router()
const Article = require('../models/article')
const User = require('./../models/users');
router.post('/signup', async(req, res, next) => {
req.user = new User()
next()
}, saveing());
function saveing() {
return async(req, res) => {
let user = req.user
user.username = req.body.username
user.password = req.body.password
try {
user = await user.save()
res.send("ok saves")
// res.render('article/new')
} catch (e) {
res.send("40004")
console.log(e)
console.log("error==============")
}
}
}
router.post('/signin', async(req, res) => {
const user = await User.findOne({
username: req.body.username,
password: req.body.password
})
if (user) {
res.render('/admin/article/new', { article: new Article() })
} else {
res.send("400404040")
}
})
module.exports = router;
sorry for my bad english

Express.js why does placement of app.use() affect test results?

I am practicing my knowledge in Express.js .
I have one recipe router with the code below:
const express = require("express");
const router = express.Router();
const Recipe = require("../models/recipe.model");
const createRecipeItem = async recipeData => {
await Recipe.init();
const doc = Recipe(recipeData);
await doc.save();
};
router.post("/", async (req, res, next) => {
try {
await createRecipeItem(req.body);
} catch (err) {
next(err);
}
res.status(201).send(req.body);
});
module.exports = router;
I have another supply router, the code is below:
const express = require("express");
const router = express.Router();
const Supply = require("../models/supply.model");
const createSupplyItem = async supplyData => {
await Supply.init();
const doc = Supply(supplyData);
await doc.save();
};
const updateItem = async (name, itemData) => {
const result = await Supply.findOneAndUpdate({ name }, itemData, {
new: true
});
return result;
};
router.post("/", async (req, res, next) => {
try {
await createSupplyItem(req.body);
} catch (err) {
next(err);
}
const respObj = {};
respObj.name = req.body.name;
respObj.qty = req.body.qty;
res.status(201).send(respObj);
});
router.patch("/:name", async (req, res, next) => {
const updatedItem = await updateItem(req.params.name, req.body);
const response = {};
response.name = updatedItem.name;
response.qty = updatedItem.qty;
res.status(200).send(response);
});
module.exports = router;
I wrote tests for the two routers using supertest
Inside my app.js my code is written like this:
const supplyRouter = require("./routes/supply.route");
const recipeRouter = require("./routes/recipe.route");
app.use("/recipes", recipeRouter);
app.use("/supplies", supplyRouter);
when the code is written like this:
app.use("/recipes", recipeRouter);
app.use("/supplies", supplyRouter);
All my test passed. However, when I change the order of when I call app.use() the test would fail.
app.use("/supplies", supplyRouter);
app.use("/recipes", recipeRouter);
The test would fail with the error Cannot set headers after they are sent to the client for the POST /supplies method. I have no clear understanding why this happens. Appreciate any insight. Thank you!
I cannot pass my test correctly because I didn't have proper understanding of the flow of the code.
router.post("/", async (req, res, next) => {
try {
await createSupplyItem(req.body);
} catch (err) {
next(err);
}
const respObj = {};
respObj.name = req.body.name;
respObj.qty = req.body.qty;
res.status(201).send(respObj);
});
For the above code, when there is an error, express will run two paths of the code namely the path inside the catch block and the last line of the code
res.status(201).send(respObj);
Because it is trying to run two paths, I received the error Cannot set headers after they are sent to the client.
The correct code is written below.
router.post("/", async (req, res, next) => {
try {
await createSupplyItem(req.body);
const respObj = {};
respObj.name = req.body.name;
respObj.qty = req.body.qty;
res.status(201).send(respObj);
} catch (err) {
if (err.name === "ValidationError") {
err.statusCode = 400;
} else if (err.name === "MongoError") {
err.statusCode = 400;
}
next(err);
}
});

Access req.user to save id to mongoDB

I'm currently having an issue with figuring out how I can access req.user so I can get the logged in users id and save it with the items that they save on the web page. That way when they load the web page they only get their items. The only place I know where I have access to req.user is in my /router/auth.js file. I want to figure out a way to access it in a different router file.
router/auth.js
const express = require('express');
const passport = require('passport');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const config = require('../config');
const router = express.Router();
const createAuthToken = function (user) {
return jwt.sign({ user }, config.JWT_SECRET, {
subject: user.username,
expiresIn: config.JWT_EXPIRY,
algorithm: 'HS256'
});
};
const localAuth = passport.authenticate('local', { session: false });
router.use(bodyParser.json());
router.post('/login', localAuth, (req, res) => {
const authToken = createAuthToken(req.user.serialize());
res.json({ authToken });
});
const jwtAuth = passport.authenticate('jwt', { session: false });
router.post('/refresh', jwtAuth, (req, res) => {
const authToken = createAuthToken(req.user);
res.json({ authToken });
});
/router/portfolio.js
router.post('/:id', (req, res) => {
const id = req.params.id;
const { holdings } = req.body;
CryptoPortfolio.findOne({ id }, (err, existingCoin) => {
if (existingCoin === null) {
getCoins(id)
.then(x => x[0])
.then(value =>
CryptoPortfolio.create({
id: value.id,
holdings,
_creator: this is where I want to add req.user.id
}).then(() => value))
.then(newItem => {
res.status(201).json(newItem);
})
.catch(err => {
console.error(err);
res.status(500).json({ message: 'Internal server error' });
});
} else {
const capitalizedId = id.charAt(0).toUpperCase() + id.slice(1);
res.json(`${capitalizedId} already in watchlist`);
}
});
});
You can define global variable and use it using middleware.
app.js
// Global Vars
app.use(function (req, res, next) {
res.locals.user = req.user
next();
});
route.js
router.get('/', function(req, res) {
CryptoPortfolio.find({}, function(err, crypto) {
console.log('CryptoPortfolio : ',crypto);
res.render('view/crypto', {
user : res.locals.user // <= here
});
});
});
I hope it would be helpful :)
I figured out that I wasn't using the code below on any of the necessary routes. Implemented it and I can now access req.user.
const jwtAuth = passport.authenticate('jwt', { session: false });

Why is my Express api register route not POSTing?

I am trying to make a small authentication system for a practice project I have. I am trying to send POST requests via postman to my express server(http://localhost:4000/api/register), and it's replying back "404 not found" I am following the tutorial here.
Here is my server.js:
const newpost = require('./routes/newpost');
const getposts = require('./routes/getposts');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const deleteposts = require('./routes/delete');
const editposts = require('./routes/editposts');
const path = require('path');
const app = express();
const webpack = require('webpack');
const webpackConfig = require('../webpack.config');
const webpackMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const passport = require('passport');
const port = 4000;
const compiler = webpack(webpackConfig);
const config = require('./config/main');
const mongoose = require('mongoose');
const authRouter = require('./routes/authrouter');
const logger = require('morgan');
// db connection
mongoose.connect(config.database);
app.use(passport.initialize());
/*
app.use(webpackMiddleware(compiler, {
noInfo: true, publicPath: webpackConfig.output.publicPath,
}));
app.use(webpackHotMiddleware(compiler, {
log: console.log,
}));
*/
app.use(cors());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
app.use(logger('dev'));
app.use('/newpost', newpost);
app.use('/posts', getposts);
app.use('/delete', deleteposts);
app.use('/edit', editposts);
//auth router to handle auth routes
authRouter(app);
/*
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, '../public/index.html'));
}); */
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
Here is my authrouter.js. These are the routes I'm exporting into my server.js. :
const AuthenticationController = require('../controllers/authentication');
const express = require('express');
// const passportService = require('../config/passport');
/* eslint-disable */
const passport = require('passport');
// Middleware to require login/auth
// const requireAuth = passport.authenticate('jwt', { session: false });
const requireLogin = passport.authenticate('local', { session: false });
module.exports = function(app){
"use-strict";
// init route groups
const apiRoutes = express.Router();
const authRoutes = express.Router();
// auth routes
// set auth routes as subgroup/middleware to apiRoutes
apiRoutes.use('/auth', authRoutes);
// Registration routes
authRoutes.post('/register', AuthenticationController.register);
// Login route
authRoutes.post('/login', requireLogin, AuthenticationController.login);
// Set url for API group routes
app.use('/api', apiRoutes);
};
Here is my authentication.js
const jwt = require('jsonwebtoken');
// const crypto = require('crypto'); used for pw resets
const User = require('../models/user');
const config = require('../config/main');
function generateToken(user) {
return jwt.sign(user, config.secret, {
expiresIn: 10080, // in seconds
});
}
// set user info from request
function setUserInfo(request) {
return {
_id: request._id,
email: request.email,
role: request.role,
};
}
// Login Route
exports.login = function (req, res, next) {
const userInfo = setUserInfo(req.user);
res.status(200).json({
token: `JWT${generateToken(userInfo)}`,
user: userinfo,
});
};
// registration route
exports.register = function (req, res, next) {
// check for registration errors
const email = req.body.email;
const password = req.body.password;
// Return error if no email provided
if (!email) {
return res.status(422).send({ error: 'You must enter an email address' });
}
// Return error if no pw provided
if (!password) {
return res.status(422).send({ error: 'You must enter a password' });
}
User.findOne({ email }, (err, existingUser) => {
if (err) { return next(err); }
// if user is not unique, return error
if (existingUser) {
return res.status(422).send({ error: 'That email address is already in use' });
}
// if email is unique and pw was provided, create acct
const user = new User({
email,
password,
});
user.save((err, user) => {
if (err) { return next(err); }
// Subscribe member to Mailchimp list
// mailchimp.subscribeToNewsLetter(user.email);
// Respond with JWT if user was created
const userInfo = setUserInfo(user);
res.status(201).json({
token: `JWT ${generateToken(userInfo)}`,
user: userInfo,
});
});
});
};
// Role authorization check
exports.roleAuthorization = function (role) {
return function (req, res, next) {
const user = req.user;
User.findById(user._id, (err, foundUser) => {
if (err) {
res.status(422).json({ error: 'No user was found' });
return next(err);
}
// if user is found, check role
if (foundUser.role == role) {
return next();
}
res.status(401).json({ error: 'You are not authorized to view this content ' });
return next('Unauthorized');
});
};
};
Here is my passport.js :
// Importing Passport; strategies; and config
const passport = require('passport');
const User = require('../models/user');
const config = require('./main');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const LocalStrategy = require('passport-local');
const localOptions = { usernameField: 'email' };
// setting up the local Strategy
const localLogin = new LocalStrategy(localOptions, ((email, password, done) => {
User.findOne({ email }, (err, user) => {
if (err) { return done(err); }
if (!user) {
return done(null, false, { error: 'Your login details could not be verified. Please try again.',
});
}
user.comparePassword(password, (err, isMatch) => {
if (err) { return done(err); }
if (!isMatch) {
return done(null, false, { error: 'Your login details could not be verified. Please try again.',
});
}
return done(null, user);
});
});
}));
const jwtOptions = {
// Telling passport to check auth headers for JWT
jwtFromRequest: ExtractJwt.fromAuthHeader(),
// Telling passport where to find the secret
secretOrKey: config.secret,
};
// setting up JWT login strategy
const jwtLogin = new JwtStrategy(jwtOptions, ((payload, done) => {
User.findById(payload._id, (err, user) => {
if (err) { return done(err, false); }
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
// allow passport to use the strategies we defined
passport.use(jwtLogin);
passport.use(localLogin);
I believe the correct post endpoint would be api/auth/register

Categories

Resources