View is not change after render .pug file from express - javascript

I have some problem that the html view is not change after render the pug file,after getting the server response.
The code is following
app.set('view engine', 'pug');
app.set("views", require('path').join(__dirname, "views"));
app.post('/login', function(req, res, next) {
console.log(req.body);
checkExistanceOfuser(req.body.username, req.body.password, function(err, flag, data) {
console.log(err);
if (err) {
res.send({
err: 'SOME_DATABASE_ERROR'
})
} else {
if (flag) {
req.session.user = data;
/*res.send({
success: true,
message: 'Login Success'
})*/
res.render('welcome', { name: data.name });
} else {
/*res.send({
success: false,
message: 'Invalid Credentials'
});*/
res.render('login', { error: 'Invalid Credentials' });
}
}
})
But i check in network section from browser.The API response (preview) is fine.

when you are calling /login route it's a post call and probably you are using ajax post call for doing so.
Now when you are calling the /login route its rendering the pug file
but its not actually effecting the browser DOM. So what you need to do is this
create a new route like this
app.get('/login-success', function(req, res, next) {
if (req.session && req.session.user) {
res.render('welcome', { name: req.session.user.name });
} else {
res.redirect('/');
}
});
and modify the login function like this
app.post('/login', function(req, res, next) {
console.log(req.body);
checkExistanceOfuser(req.body.username, req.body.password, function(err, flag, data) {
console.log(err);
if (err) {
res.send({
err: 'SOME_DATABASE_ERROR'
})
} else {
if (flag) {
req.session.user = data;
res.send({
success: true,
message: 'Login Success'
});
} else {
res.send({
success: false,
message: 'Invalid Credentials'
});
}
}
})
});
in ajax call use this
function login(){
$.post("http://localhost:8000/login",
{
username:document.getElementById("name").value,
password:document.getElementById("password").value,
},
function(data, status){
if(data.success){
window.location = "http://localhost:8000/login-success"
}
});
}

You're rendering views/login, but you've already specified that the view folder is views. Just render login.

Related

req.isAuthenticated() never evaluates to true

I'm trying to implement user authentication as below:
userRouter.post("/login", passport.authenticate("local", { session: false }), (req, res) => {
if (req.isAuthenticated()) {
const { _id, username } = req.user;
const token = signToken(_id);
res.cookie("access_token", token, { httpOnly: true, sameSite: true });
res.status(200).json({ isAuthenticated: true, user: { username } });
}
});
But to be able to add some custom messages I'm using the alternative below:
userRouter.post('/login', (req, res, next) => {
passport.authenticate('local',{ session: false }, (err, user, info) => {
if (req.isAuthenticated()) {
const { _id, username } = req.user;
const token = signToken(_id);
res.cookie("access_token", token, { httpOnly: true, sameSite: true });
res.status(200).json({ isAuthenticated: true, user: { username } });
}
if (err) return next(err)
if (info)
res.status(400).json({ message: { msgBody: info.message, msgError: true } });
})(req, res, next);
});
However, in the second alternative, it seems like req.isAuthenticated() is never evaluated to true.
Can anyone help me understand why?
Thanks
The passport docs say "Note that when using a custom callback, it becomes the application's responsibility to establish a session (by calling req.login()) and send a response." (http://www.passportjs.org/docs/authenticate/)
With the follow code as an example:
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);
});
I wonder if it says you are not authenticated because you need to call the login method?

Node.js passport authentication ignores controller function

If passport returns the user { status: 200 }:
passport.js
...
return done(null, rows[0], { status: 200 });
...
I want the controller 'controllerLogin.login' to be called:
routs/index.js
const express = require('express');
const passport = require('passport');
const passportConf = require('../passport');
const controllerLogin = require('../controllers/login');
...
router.route('/v1/login')
.post( function(req, res, next) {
passport.authenticate('local-login', function (err, user, context = {}) {
if (err) {
console.log(err);
}
if (context.status === 429) {
return res.status(429).send({ status: 429, success: false })
}
if (context.status === 401){
return res.status(401).send({ status: 401, success: false })
}
next();
//return;
})(req, res, next);
}, controllerLogin.login );
But I can't reach the controller 'controllerLogin.login'. What am I missing and how to execute 'controllerLogin.login'?
The below was working, but I need the upper version.
const passLogin = passport.authenticate('local-login', { session: false, failWithError: true });
router.route('/v1/login')
.post( passLogin, function(err, req, res, next) {
return res.status(401).send({ status: 401, success: false })
}, controllerLogin.login );
Edit: What works ...
router.route('/v1/login')
.post( function(req, res, next) {
passport.authenticate('local-login', { session: false, failWithError: false }, function (err, user, context = {}) {
if (err) {
console.log(err);
}
if (context.statusCode === 429) {
return res.status(429).send({ status: 429, success: false, message: { name: 'Rate Limit Error' } })
}
if (context.statusCode === 401){
return res.status(401).send({ status: 401, success: false, message: { name: 'Authentication Error' } })
}
// this works getting user information
console.log('user:');
console.log(user);
next();
})(req, res, next);
}, /*controllerLogin.login*/ (req, res) => { res.status(200).json({just: 'testing'})} );
controller/login.js
module.exports = {
login: async (req, res, next) => {
// Can't access user information via 'req.user' anymore
console.log('req.user:');
console.log(req.user);
/* .. How to access user information here? .. */
res.status(200).json({just: 'testing'})
}
}
It sounds like controllerLogin.login wants req.user, but that is not being set. So try doing that manually in the callback you pass in to passport's authenticate function.
router.route('/v1/login')
.post( function(req, res, next) {
passport.authenticate('local-login', { session: false, failWithError: false }, function (err, user, context = {}) {
if (err) {
console.log(err);
return next(err); // might want to add this line to handle errors?
}
if (context.statusCode === 429) {
return res.status(429).send({ status: 429, success: false, message: { name: 'Rate Limit Error' } })
}
if (context.statusCode === 401){
return res.status(401).send({ status: 401, success: false, message: { name: 'Authentication Error' } })
}
if(!user) {
// might want to handle this separately? user not found?
//return next('User not found');
}
// this works getting user information
console.log('user:');
console.log(user);
req.user = user;
next(); // this moves us on to controllerLogin.login
})(req, res, next);
}, controllerLogin.login);
Then in controller/login
module.exports = {
login: (req, res) => {
// remove user logging once this works, don't want to log sensitive info (!)
console.log('req.user in controller/login:')
console.log(req.user)
// user logic here
res.status(200).json({status: 200, success: true})
}
}
It's worth taking a look at passportjs docs under the "Custom Callback" section. That example doesn't pass along to another function as you are doing, but it can help to see another approach.

node js callback function issue

i am new to developing apis in node js. recently i started working on a node js application there i use jwt tokens to authentication purposes.
my jwt validation function is as bellow
var jwt = require('jsonwebtoken');
var config = require('../config.js')
var JwtValidations = {
//will validate the JTW token
JwtValidation: function(req, res, next, callback) {
// 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.secret, callback);
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
}
}
module.exports = JwtValidations;
to this function i am passing a call back function so that if the jtw token validation passed i can serve to the request. bellow is one example of adding a user to the system
// addmin a user to the database
router.post('/add', function(req, res, next) {
JwtValidations.JwtValidation(req, res, next, function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
retrunval = User.addUser(req.body);
if (retrunval === true) {
res.json({ message: "_successful", body: true });
} else {
res.json({ message: "_successful", body: false });
}
}
})
});
// addmin a user to the database
router.put('/edit', function(req, res, next) {
JwtValidations.JwtValidation(req, res, next, function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
User.UpdateUser(req.body, function(err, rows) {
if (err) {
res.json({ message: "_err", body: err });
} else {
res.json({ message: "_successful", body: rows });
}
});
}
})
});
as you can see in both of these function i am repeating same code segment
return res.json({ success: false, message: 'Failed to authenticate token.' });
how do i avoid that and call the callback function if and only if JwtValidations.JwtValidation does not consists any error
how do i avoid that and call the callback function if and only if JwtValidations.JwtValidation does not consists any error
Just handle it at a level above the callback, either in JwtValidations.JwtValidation itself or a wrapper you put around the callback.
If you were doing it in JwtValidations.JwtValidation itself, you'd do this where you call the callback:
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.secret, function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
}
callback(decoded);
});
} else /* ... */
Now when you use it, you know either you'll get the callback with a successfully-decoded token, or you won't get a callback at all but an error response will have been sent for you:
router.put('/edit', function(req, res, next) {
JwtValidations.JwtValidation(req, res, next, function(decoded) {
User.UpdateUser(req.body, function(err, rows) {
if (err) {
res.json({ message: "_err", body: err });
} else {
res.json({ message: "_successful", body: rows });
}
});
})
});
The code above is using a lot of (old-style) NodeJS callbacks. That's absolutely fine, but you may find it's simpler to compose bits of code if you use promises instead. One of the useful things do is split the return path in two, one for normal resolution, one for errors (rejection).
Use the jwt authentication function as a middleware function and not as a route, plenty of examples on the express documentation.
http://expressjs.com/en/guide/using-middleware.html

Keystone CMS Rest API authentication

So i am new comer to keystone CMS and its looking awesome to me
i have setup the basic structure and using a default blog project provided by keystone so now i am trying to build the rest API for my admin
As the rest API working fine when i am loged in browser in keystone admin panel but when i am testing the same is postman even after setting the basic auth it giving me HTML page
I don't know what the wrong with that and how to setup this thing correctly.
Here is my code from index.js
var _ = require('underscore'),
keystone = require('keystone'),
middleware = require('./middleware'),
// restful = require('restful-keystone-onode')(keystone),
importRoutes = keystone.importer(__dirname);
// Common Middleware
keystone.pre('routes', middleware.initLocals);
keystone.pre('render', middleware.flashMessages);
// Import Route Controllers
var routes = {
views: importRoutes('./views'),
api: importRoutes('./api'),
};
// create a route that handles signin
function signin (req, res) {
if (!req.body.username || !req.body.password) return res.json({
success: false });
keystone.list('User').model.findOne({ email: req.body.username
}).exec(function (err, user) {
if (err || !user) {
return res.json({
success: false,
session: false,
message: (err && err.message ? err.message : false) || 'Sorry,
there was an issue signing you in, please try again.',
});
}
keystone.session.signin({ email: user.email, password:
req.body.password }, req, res, function (user) {
return res.json({
success: true,
session: true,
date: new Date().getTime(),
userId: user.id,
});
}, function (err) {
return res.json({
success: true,
session: false,
message: (err && err.message ? err.message : false) || 'Sorry,
there was an issue signing you in, please try again.',
});
});
});
}
// you'll want one for signout too
function signout (req, res) {
keystone.session.signout(req, res, function () {
res.json({ signedout: true });
});
}
// also create some middleware that checks the current user
// as long as you're using Keystone's session management, the user
// will already be loaded if there is a valid current session
function checkAuth (req, res, next) {
// you could check user permissions here too
if (req.user) return next();
return res.status(403).json({ error: 'no access' });
}
// Setup Route Bindings
exports = module.exports = function (app) {
// Views
app.get('/', routes.views.index);
app.get('/blog/:category?', routes.views.blog);
app.get('/blog/post/:post', routes.views.post);
app.get('/gallery', routes.views.gallery);
app.all('/contact', routes.views.contact);
// add an API endpoint for signing in _before_ your protected routes
app.post('/api/signin', signin);
app.post('/api/signout', signout);
// then bind that middleware in your routes before any paths
// that should be protected
app.all('/api*', checkAuth);
//
app.get('/api/post/list', keystone.middleware.api,
routes.api.posts.get);
app.get('/api/post/:id', keystone.middleware.api,
routes.api.posts.get);
};
and here is my route/api/post.js
/**
* Created by nikk on 11/5/17.
*/
var async = require('async'),
keystone = require('keystone');
var Post = keystone.list('Post');
/**
* List Posts
*/
exports.list = function(req, res) {
Post.Modal.find(function(err, items) {
if (err) return res.apiError('database error', err);
// res.apiResponse({
// posts: items
// });
res.json(items);
});
}
/**
* Get Post by ID
*/
exports.get = function(req, res) {
Post.model.findById(req.params.id).exec(function(err, item) {
if (err) return res.apiError('database error', err);
if (!item) return res.apiError('not found');
res.apiResponse({
post: item
});
// res.json(item);
});
}
I have been trying hard to get this thing done from last day but not able to do working till now
please guide me.

No default engine when registering user

Error: No default engine was specified and no extension was provided.
Im getting this error when I try to register a new user in my MEAN app. Im not using a view engine.
I've specified a static path (Node server.js):
app.use(express.static(path.join(__dirname + '/public')));
I've also specified a route to handle all angular requests
app.get('*', function (req, res) {
res.sendFile(path.resolve('public/index.html'));
});
The error occurs in this function (Angular authService.js):
function register(email, password) {
// create a new instance of deferred
var deferred = $q.defer();
// send a post request to the server
$http.post('/user/register',
{email: email, password: password})
// handle success
.success(function (data, status) {
if (status === 200 && data.status) {
deferred.resolve();
} else {
deferred.reject();
}
})
// handle error
.error(function (data) {
deferred.reject();
});
// return promise object
return deferred.promise;
}
(Node routes.js):
router.post('/register', function(req, res) {
User.register(new User({ email: req.body.email }),
req.body.password, function(err, user) {
if (err) {
return res.status(500).json({
err: err
});
}
passport.authenticate('local')(req, res, function () {
return res.status(200).json({
status: 'Registration successful!'
});
});
});
});
I've done some logging and the post function in angular never reaches my routes.js
I've tried other post/get/put calls using Postman, and I get the same error.

Categories