call function object from route in express js - javascript

My code looks something like this:
router.route('/user')
.post(function(req, res, next){
queryDB(arg1, arg2, prepareRes)
})
.get(function(req, res, next){
queryDB(arg3, arg4, prepareRes)
});
var prepareRes = function(err, data){
if(err) next(err);
else{
req.data = data;
}
};
when i run this code i get the following error:
ReferenceError: next is not defined
or
ReferenceError: req is not defined
This happens because req and next ,are outside prepareRes scope.
How can get around this ERROR??
I don't want to have to duplicate the same lines of code in both routes and its not possible to use
route.all
in my case.

prepareRes is declared outside of the post and get handlers so it has no access to the req(uest) or next.
The most obvious solution is to add request and next parameters to the prepareRes function signature and then, when calling prepareRes in the request handlers, to wrap the call in an anonymous function that can access them:
router.route('/user')
.post(function(req, res, next){
queryDB(arg1, arg2, function(err, data){
prepareRes(err,data, req, next);
})
})
.get(function(req, res, next){
queryDB(arg3, arg4, function(err, data){
prepareRes(err,data, req, next);
})
});
var prepareRes = function(err, data, req, next){
if(err) next(err);
else{
req.data = data;
}
};
Using something like lodash you you could get rid of the anonymous functions and partially apply the additional arguments like so:
queryDB(arg1, arg2, _.partialRight(prepareRes, res, next));
But you still have to change the prepareRes signature.

since prepareRes is not inside of any of the above functions, where req,res are provided it can not find req on its namespace, assuming req and next are not globals.
Here for instance: req and next are passed to an error handler function:
function clientErrorHandler(err, req, res, next) {
if (req.xhr) {
res.status(500).send({ error: 'Something blew up!' });
} else {
next(err);
}
}
Then next and res is available in the scope.

Related

I don't understand the syntax of the following javaScript code

else{
passport.authenticate("local")(req, res, function () {
res.redirect("/secrets");
});
}
Why is there no "." after authenticate("local") (here)and before (req, res, function () .........)
passport.authenticate returns a function. That returned function can then be called (like any function) - req, res, and another callback function are arguments that can be passed.
If you're finding it difficult to read, it might make more sense to break the returned function out into its own identifier.
const passportHandler = passport.authenticate("local");
passportHandler(req, res, function () {
res.redirect("/secrets");
});
Often, an even better approach would be to for the Passport middleware to be declared for the route itself, instead of declaring both a route callback and then passing down the req and res again. That is
app.post(
'someEndpoint',
passport.authenticate("local"),
(req, res) => {
res.redirect("/secrets");
}
)
if you can figure out a way around the else. passport.authenticate returns a route handler callback, and the (req, res) => is also a route handler callback..

node express: mock authorize function in app.get

I'm practicing with simple .get methods in node/express. I'm following an example of a book, but I have no session variable and i have no templates; so i've commented that lines and i've replaced them with a simple .send method, and i've replaced with a simple hardcode variable: authorized.
I'm getting the error: ReferenceError: res is not defined
The problem is that I have no res variable, because the control pass first on authorize function.
function authorize(req, res, next){
authorized = true;
// if(req.session.authorized) return next();
if(authorized) return next();
res.send('not-authorized');
}
app.get('/secret', authorize, function(){
// res.render('secret');
res.send('secret');
});
app.get('/sub-rosa', authorize, function(){
// res.render('sub-rosa');
res.send('sub-rosa');
});
thanks to comments, the solution is:
function authorize(req, res, next){
authorized = true;
// if(req.session.authorized) return next();
if(authorized) return next();
res.send('not-authorized');
}
app.get('/secret', authorize, function( req, res ){
// res.render('secret');
res.send('secret');
});
app.get('/sub-rosa', authorize, function( req, res ){
// res.render('sub-rosa');
res.send('sub-rosa');
});

Node.js User Authentication

I'm new with nodeJs and i'm actually following a tutorial about it.
In the tutorial, a code was used:
In a verify.js file the following function was written:
exports.verifyOrdinaryUser = function (req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.secretKey, function (err, decoded) {
if (err) {
var err = new Error('You are not authenticated!');
err.status = 401;
return next(err);
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
var err = new Error('No token provided!');
err.status = 403;
return next(err);
}
};
and in another file, the function was called so :
/*****........****/
.post(verify.verifyOrdinaryUser, function(req, res, next){
/******.......*****/
everything is working fine without problem.
1- I don't understand why the function verify.verifyOrdinaryUser is not called so :
verify.verifyOrdinaryUser(req, res, next)
with his parameter (how is it possible that we call a function without his parameter .?
next , i've written a function :
exports.verifyAdmin = function(req, res, next){
if(req.decoded._doc.admin == false){
var err = new Error('You cannot access to this ressource!');
err.status = 401;
return next(err);
}
else {
next();
}
};
in the same file, to verify if a user is a admin or not, i have to call this function after the verifyOrdinaryUser function,
my problem is i don't know how i can make call of this function, with or without the parameters.
Thank you.
1- I don't understand why the function verify.verifyOrdinaryUser is
not called so : verify.verifyOrdinaryUser(req, res, next)
In simplest terms, That's because Express takes care of sending those parameters to the specified middleware instead of you specifying it here
And in function verify.verifyOrdinaryUser, The function is requesting for 3 parameters req, res, next and it receives those three parameters, if it requests for a parameter that doesn't exist, That parameters value will be undefined.
my problem is i don't know how i can make call of this function, with
or without the parameters.
Just call it like
/*****........****/
.post(verify.verifyOrdinaryUser, verify.verifyAdmin, function(req, res, next){
/******.......*****/
And in the functions code you can request for the parameters you need
exports.verifyAdmin = function(req, res){
if(req.decoded._doc.admin == false){
...
Hope this gives you some sense on whats going on, You should google for Node JS Middlewares and simple tutorials based on Node JS and Express.

passportjs custom callback code flow

I am new to passportJS, and want to understand this code:
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
Can someone explain to me flow of this code? and what (req, res, next); do in the end of passport.authenticate function?
I already read this question too, but still don't get it.
passport.authenticate()(<args>);
passport.authenticate() returns a function that can have three arguments (req,res,next). The code/arguments that you are asking about are these arguments which are passed to the function that is returned by passport.authenticate() Check the authenticate.js code on GitHub
However, I am not very clear about what does passport do with string local. I would like to know:
Is passing local string sufficient for Passport to understand what
authentication mechanism to apply?
What does passport do (and how) after encountering use of local strategy?

Using middleware with app.use

what is the difference between:
function setLocale(req, res, next) {
req.params.locale = req.params.locale || 'pt';
res.cookie('locale', req.params.locale);
req.i18n.setLocale(req.params.locale);
console.log(req.params.locale);
next();
}
app.get('/:locale?', setLocale, function(req, res) {
res.render("index");
});
And this:
app.use(setLocale);
function setLocale(req, res, next) {
req.params.locale = req.params.locale || 'pt';
res.cookie('locale', req.params.locale);
req.i18n.setLocale(req.params.locale);
console.log(req.params.locale);
next();
}
app.get('/:locale?', function(req, res) {
res.render("index");
});
??
Only the first is working, if i try to use app.use, the code will broke cause req.params.locale will be undefined.
The problem is that when you use app.use(setLocale); all you calls will be passed that function. Even if you call the url / that code will run and then param will be undefined.
The fisrt option you have (app.get('/:locale?', setLocale,) you use that function only when that url matches and there is a locale that you can use inside the function.
app.use will add the middleware to the stack and use it before each request is processed, always, regardless of route, method etc.
In the first example the middleware is added as a callback function to that route only, as app.get accepts multiple callbacks, and calling next moves to the next callback etc
app.get('/', function(req, res, next) {
next(); // move to next
}, function(req, res, next) {
// continues here when next() is called in previous callback etc.
});
this means that in the first example the setLocale function is only called when the route matches /:locale?, while in the second example using app.use will always call the setLocale function before the routes callback is executed.
Unfortunately req.params is not available in app.use as it depends on the router and is added later, so you're probably stuck with including the function as a callback to every route, and you could probably do that with app.all('*')
function setLocale(req, res, next) {
req.params.locale = req.params.locale || 'pt';
res.cookie('locale', req.params.locale);
req.i18n.setLocale(req.params.locale);
next();
}
app.all('*', setLocale);
app.get('/:locale?', function(req, res) {
res.render("index");
});

Categories