how to properly inject middleware in NodeJS route - node.js

How can i inject my middleware function 'checkAuthenticated' into my get route below?
not sure how to properly inject the code below. Please let me know. thank you very much.
function checkAuthenticated(req, res, next) {
if(!req.header('authorization')) {
return res.status(401).send({message: 'Unauthorized request. Missing authentication header'});
}
let token = req.header('authorization').split(' ')[1];
let payload = jwt.decode(token, '123');
if(!payload) {
return res.status(401).send({message: 'Unauthorized request. Authetication header invalid'});
}
req.user = payload;
next();
}
router.route('/:user_id')
.get((req, res) => {
User.findById(req.params.user_id, (err, user) => {
if (err) {
res.send(err);
} else {
res.json(user);
}
});
})

There are a few options here. I typically use:
router.use('*', checkAuthenticated);
Another option is:
router.get('/:user_id', checkAuthenticated, (req, res) => { ... })
Or, using your example of router.route...:
router.route('/:user_id').get(checkAuthenticated, (req, res) => { ... })
You can also chain them together:
router.route('/:user_id').get(checkAuthenticated).get((req, res) => { ... })

check this hope it will help you
router.route('/:user_id')
.all((req, res, next) => {
if (req.user) {
next();
} else {
res.redirect('/');
}
})
.get((req, res) => {
res.json(req.user);
});

Related

when i call api result is json with empty object solve this problem

when I call api the result is empty object
here is my code
router.get('/register', (req, res) => {
const user = User.find({}, function(err, users){
if(err){
console.log(err);
}
else {
res.json(users);
}
});
});
router.post('/register', (req, res, next) => {
User.create(req.body).then(user => {
res.send(user);
}).catch(next);
});
I hope this will help you. Or if you want to assign a variable.
router.post('/register', (req, res, next) => {
const {username, password, email, phone} = req.body;
User.create(req.body).then(user => {
res.send({username, password, email, phone});
}).catch(next);
});

passing data to partial express js hbs

currently I am making a notification system with node/express/hbs and mysql. I can insert notification to the database properly , but I can't fetch it my partial file.
here is my code
countNotification: async (req, res) => {
await Notification.count({ where: { status: 'unread' } }).then((notification) => {
if (notification) {
const dashNotification = req.notification;
return dashNotification;
}
});
},
app.use((req, res, next) => {
res.locals.user = req.user;
res.locals.notification = req.dashNotification;
next();
});
i have tried this like that but it is not working , anyone has any solution ?
You should use your middleware above the router:
app.use((req, res, next) => {
res.locals.user = req.user;
res.locals.notification = req.dashNotification;
next();
});
countNotification: async (req, res) => {
await Notification.count({ where: { status: 'unread' } }).then((notification) => {
if (notification) {
const dashNotification = req.notification;
return dashNotification;
}
});
},

How to redirect/render to 404 if the "_id" is wrong/misspelled in /blogs/:blogId

I want to redirect users to "404.ejs" if the post id is entered wrong/mispelled in blogs/:blogId route. How can I accomplish it in below code.
app.get('/blogs/:blogid', (req, res) => {
const requestedId = req.params.blogid;
Blog.findById(requestedId, (err, addedblogpost) => {
if (err) {
console.log(err);
}
else {
res.render("post", {
title: addedblogpost.blogTitle,
content: addedblogpost.blogContent
})
}
})
}
Code for "404"
app.get('*', (req, res) => {
res.render('404');
})
You should make use of express next parameter to get the result you want.
This will call the next "matching" middleware for the current route, assuming this would be your error handler middleware of course.
It should be used as shown below :
app.get('/blogs/:blogid', (req, res, next) => {
const requestedId = req.params.blogid;
Blog.findById(requestedId, (err, addedblogpost) => {
if (err) {
next();
}
else {
res.render("post", {
title: addedblogpost.blogTitle,
content: addedblogpost.blogContent
})
}
})
Express doc : https://expressjs.com/en/guide/using-middleware.html
app.get('/blogs/:blogid', async (req, res) => {
const requestedId = req.params.blogid;
const blog = await Blog.findById(requestedId);
if (!blog) return res.render("404");
res.render("post");
}
to check if the blog is null or not.

Is there a way to avoid multiple next() in express middleware

This is how I've designed my route and I'm not really happy with it. I'd rather be able to break down each hasValid into its own middleware, but I don't see how that would work since it wouldn't stop execution.
const secretSender = async (req, res, next) => {
if (!hasValidA(req)) {
return next()
}
if (!hasValidB(req)) {
return next()
}
if (!hasValidC(req)) {
return next()
}
if (!hasValidD(req)) {
return next()
}
res.send('something secret')
}
router.use(secretSender)
router.get('*', (req, res) => {
res.send('something public')
})
It also doesn't really make sense to make the default route "something secret" and have "something public" be the middleware since "something public" is the default behavior.
Here's one way to break down each hasValid into its own middleware. Each middleware will short-circuit the execution if the outcome is valid:
const validA = async (req, res, next) => {
if (hasValidA(req)) {
res.send('something secret')
} else {
next()
}
}
const validB = async (req, res, next) => {
if (hasValidB(req)) {
res.send('something secret')
} else {
next()
}
}
const validC = async (req, res, next) => {
if (hasValidC(req)) {
res.send('something secret')
} else {
next()
}
}
const validD = async (req, res, next) => {
if (hasValidD(req)) {
res.send('something secret')
} else {
next()
}
}
router.use(validA, validB, validC, validD)
router.get('*', (req, res) => {
res.send('something public')
})
Update
To achieve somewhat similiar result with OP's code, but only with single next():
const secretSender = async (req, res, next) => {
if (hasValidA(req) && hasValidB(req) && hasValidC(req) && hasValidD(req)) {
res.send('something secret')
} else {
next()
}
}
router.use(secretSender)
router.get('*', (req, res) => {
res.send('something public')
})

middleware is not working in nodejs

I have this code:
exports.get_transducer_edit = (req, res) => {
if(req.isAuthenticated()){
Transducer.findById(req.params.id, (err, foundTransducer) => {
if(err){
res.redirect('/en/dashboard');
} else {
res.render('dashboard/transducer_edit-dashboard', {transducer: foundTransducer});
}
});
}else{
req.flash('error','You need to log in to do that');
res.redirect('/dashboard/login');
}
};
it runs with no problem, but then when I created a middleware in middleware/index.js:
var middlewareObj = {};
middlewareObj.isLoggedIn = function(req, res, next){
if(req.isAuthenticated() ) {
return next();
}
res.redirect('/dashboard/login');
};
module.exports = middlewareObj;
I called it inside this code:
const middleware = require('../middleware');
const Transducer = require('../models/productTransducers');
exports.get_transducer_edit = middleware.isLoggedIn, (req, res) => {
Transducer.findById(req.params.id, (err, foundTransducer) => {
if(err){
res.redirect('/en/dashboard');
} else {
res.render('dashboard/transducer_edit-dashboard', {transducer: foundTransducer});
}
});
};
What am I doing wrong? Please help...
Sorry, I just solved.
I called the middleware in my route:
router.get('/en/dashboard/products/transducers/:id/edit', middleware.isLoggedIn, transducer_controller.get_transducer_edit);
I was trying to call it in my controller like:
exports.get_transducer_edit = middleware.isLoggedIn, (req, res) => {
...
wrong!
Thanks again.

Resources