How can i switch to another user account from an admin account - node.js

I have a user table in which i have an Admin account and some other normal users accounts.
I want to do all activities which for a particular user. It should act like that activity done by same user.
Can somebody tell me how can i switch to another account from Admin account
without login to that account.
Currently i use passport authentication.(passport-local)
Here is my code
app.get('/secure/group/login', function(req,res,next) {
passport.authenticate('local',function(err,user,info) {
console.log("error is "+err);
req.logIn('tessAccount',function(err) {
console.log("Weer" +err);
});
console.log("dd");
})(req,res,next);
});
});
and passport code
var LocalStrategy = require('passport-local').Strategy;
module.exports = function(passport) {
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.token);
});
passport.use(new BearerStrategy(
function(token, done) {
user.tokenExist(token, function(err, user) {
if (err) {
return done(err);
}
else {
return done(null, user, { scope: 'all' });
}
});
}
));
// used to deserialize the user
passport.deserializeUser(function(accessToken, done) {
user.getUserByAccessToken(accessToken, function(err, dbUser) {
if (err) {
done(err);
} else {
done(null, dbUser[0]);
}
});
});
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
user.emailExists(email, function(err, exists) {
if (err)
return done(err);
else if (exists) {
return done(null, false, {
message: req.flash('loginMessage')
});
} else {
req.userDetails.status = 0;
req.userDetails.token = md5.digest_s(req.userDetails.email + new Date());
req.userDetails.userImage = config.user.image;
user.register(req.userDetails, function(err, newUser) {
if (err)
return done(err);
else {
/*Get user Shared article if exist start*/
getSharedArticlesOfnewlyuserIfExist(email, newUser.insertId);
/*Get user Shared article if exist end*/
req.userDetails.id = newUser.insertId;
return done(err, req.userDetails);
}
});
}
});
}));
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
user.matchPassword({
email: email,
password: password
}, function(err, newUser) {
// if there are any errors, return the error before anything else
if (err)
return done(err);
// if no user is found, return the message
if (newUser.length > 0) {
var user = {
id: newUser[0].user_id,
email: newUser[0].email_id,
token: newUser[0].user_access_token
};
return done(null, user);
} else {
return done(null, false, {
message: 'Incorrect username or password.'
}); // req.flash is the way to set flashdata using connect-flash
}
});
}));

User.findOne({ username: 'Myusername' }, function(err, user) {
req.logIn(user, function(err){});
});
This worked for me to log into an account without using password, it switches from my admin account to an user account.
Actually I'm using passport.js and mongoose

Related

Failing to authenticate user on login with passport and bcrypt

So I am trying to create a signup/login logic for my website using passport and bcrypt-nodejs for password hashing. I am successful at registering a user, but then on login I always get into the 'false' branch for password authentication and am getting my console message for 'Wrong Password' Here is my login passport code:
passport.use('user-local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'email' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done(err);
// if no user is found, return the message
if (!user) {
console.log('No user found.');
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
}
bcrypt.compare(password, user.password, function(err, res) {
if (err)
throw err;
if(!res) {
console.log('Ooops!. Wrong Pass!');
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
}
return done(null, user);
});
});
}));
And here is my signup logic
passport.use('user-local-signup', new LocalStrategy({
usernameField : 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function (req, email, password, done) {
// asynch
// User.findOne will not fire unless data is sent back
process.nextTick(function() {
User.findOne({'email' : email}, function (err, user) {
if(err)
return done(err);
if(user) {
console.log('That email is already taken');
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// checks for password and repeat_password match
if (password != req.body.repeat_password) {
console.log('Passwords do not match.');
return done(null, false, req.flash('signupMessage', 'Passwords do not match.'));
}
var newUser = new User();
newUser.email = email;
bcrypt.hash(password, null, null, function(err,hash){
if (err)
throw err;
else {
newUser.password = hash;
}
});
newUser.save(function(err) {
if(err)
throw err;
return done(null, newUser);
});
console.log('New user was created: ' + email);
}
});
});
}));

passport.js hangs on some posts

I've been searching stackoverflow for reasons why my node.js (express) app hangs on some posts with passport.js.
I've been looking at theese two questions:
More Passport.js woes - hangs on form submission
Passport (local) is hanging on Authentication
My code for creating a user works fine, and looks like this:
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function(req, email, password, done) {
if (email)
email = email.toLowerCase(); // Use lower-case e-mails to avoid case-sensitive e-mail matching
// asynchronous
process.nextTick(function() {
// if the user is not already logged in:
if (!req.user) {
User.findOne({
where: {
local_email: email
}
}).then(function(user) {
if (user){
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
}else{
// create the user
User
.build({
local_email: email,
local_password: generateHash(password),
id: 1 //Normal activated user
})
.save()
.then(newUser => {
//Our newly crated user
return done(null, newUser);
})
.catch(error =>{
//Woops something went wrong
return done(error);
})
//var newUser = new User();
//newUser.localemail = email;
//newUser.localpassword = generateHash(password);
//User.create(newUser).then(function(newUser, created) {
// if (!newUser) {
// return done(err);
// }
// if (newUser) {
// return done(null, newUser);
// }
//});
}
});
// if the user is logged in but has no local account...
} else if ( !req.user.local.email ) {
// ...presumably they're trying to connect a local account
// BUT let's check if the email used to connect a local account is being used by another user
User.findOne({
where: {
localemail: email
}
}).then(function(user) {
if (err)
return done(err);
if (user){
return done(null, false, req.flash('loginMessage', 'That email is already taken.'));
// Using 'loginMessage instead of signupMessage because it's used by /connect/local'
} else {
// create the user
var newUser = new User();
newUser.local.email = email;
newUser.local.password = generateHash(password);
User.create(newUser).then(function(newUser, created) {
if (!newUser) {
return done(err);
}
if (newUser) {
return done(null, newUser);
}
});
}
});
} else {
// user is logged in and already has a local account. Ignore signup. (You should log out before trying to create a new account, user!)
return done(null, req.user);
}
});
}));
In my routs file the post to that function looks like this:
// process the signup form
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
My code for signing in however dosen't work that well. The function in passport.js looks like this:
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function(req, email, password, done) {
if (email)
email = email.toLowerCase(); // Use lower-case e-mails to avoid case-sensitive e-mail matching
// asynchronous
process.nextTick(function() {
User.findOne({
where: {
local_email: email
}
}).then(function(user){
console.log("TEST: "+user);
// if no user is found, return the message
if (!user){
console.log("no user with the following email: " +email);
return done(null, false, req.flash('loginMessage', 'No user found.'));
}else if(!validPassword(password,user.local_password)){
console.log("wrong password");
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
// all is well, return user
}else{
return done(null, user);
return;
}
}).catch(function(err){
console.log("woops der skete en fejl: "+err);
console.log("email is: "+email);
console.log("password is: "+password);
return done(err);
});
});
}));
The corresponding route looks like this:
// process the login form
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/', // redirect to the secure profile section
failureRedirect : '/login', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
The above code hangs when the form is being submitted. If I changes the code to:
app.post('/login', function(req, res, next) {
passport.authenticate('local-login', function(err, user, info) {
if (err) { return next(err); }
if (!user) {
return res.render('/login', {
pageTitle: 'Sign in',
form: req.body
});
}
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/');
});
})(req, res, next);
});
I receive an 500.
Any ideas why this isen't working?
Updated with console output:
Executing (default): SELECT `id`, `role`, `local_email`, `local_password`, `facebook_id`, `facebook_token`, `facebook_email`, `facebook_name`, `twitter_id`, `twitter_token`, `twitter_displayname`, `twitter_username`, `google_id`, `google_token`, `google_email`, `google_name`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`local_email` = 'test#local' LIMIT 1;
TEST: [object SequelizeInstance:users]
POST /login 302 87.021 ms - 46
Executing (default): SELECT `id`, `role`, `local_email`, `local_password`, `facebook_id`, `facebook_token`, `facebook_email`, `facebook_name`, `twitter_id`, `twitter_token`, `twitter_displayname`, `twitter_username`, `google_id`, `google_token`, `google_email`, `google_name`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`id` = 1;
Updated with changed passport.deserializeUser
passport.deserializeUser(function(id, done) {
/*User.findById(id, function(err, user) {
done(err, user);
});*/
User.findById(id).then(user => {
if (!user){
done(null);
}else{
done(user);
}
})
});
Your passport.deserializeUser isn't correct. As with all Node.js callbacks, the first argument is reserved for errors, and should be null (or another falsy value) if there aren't any errors. In your case, you're passing user as first argument, which makes Passport think there was an error.
Try this:
passport.deserializeUser(function(id, done) {
User.findById(id)
.then(user => done(null, user))
.catch(done);
});

PassportJS not redirecting upon save

I am trying to redirect a user once he signs up or if the username is already present in the db, the function works well but I can not redirect and I am totally confused on what to do next.
Here is my passport file
var LocalStrategy = require('passport-local').Strategy;
var User = require('./models/user');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user);
});
// used to deserialize the user
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'email' : email }, function(err, user) {
// if there are any errors, return the error
if (err) {
return done(err);
}
if(user) {
if(user.validPassword(password)) {
return done(null, user);
} else {
return done(null, true, req.flash('signupMessage', 'That email is already in DB.'));
}
} else {
var newUser = new User();
newUser.email = email;
newUser.password = newUser.generateHash(password);
newUser.save(function(err) {
if (err)
return done(err);
return done(null, newUser);
});
}
});
});
}));
}
and my route
app.post('/signup',passport.authenticate('local-signup', {
successRedirect : '/timeslot', // redirect to the secure profile section
failureRedirect : '/', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
I have also tried doing
app.post('/signup',function(req, res, next) {
passport.authenticate('local-signup', function(err, user, info) {
if (user) {
res.redirect('/timeslot');
}
else res.redirect('/');
})(req, res, next);
});
but it is not working at all. I am desperate to fix this but dont know how.
I met the same problems with passport redirects. So my code began work just as
app.get("/auth/facebook/callback", passport.authenticate("facebook", { failureRedirect: config.loginPage }), function(req,res) {
res.redirect(config.redirectAfterLogin);
});

Credentials are not getting passed to authentication stategy

I'm new to node express and passport so I'm not sure what I'm missing. I'm trying to use a custom callback as all I want is a json response from my registration strategy. Currently I keep getting the following error "Missing credentials". I've been at it for a while now and I'm stuck.
Here is my controller:
app.post('/services/authentication/registration', function(req, res, next) {
console.log('before authentication')
passport.authenticate('local-registration', function(err, user, info) {
console.log('authentication callback');
if (err) { return res.send({'status':'err','message':err.message});}
if (!user) { return res.send({'status':'err','message':info.message});}
if (user!=false) { return res.send({'message':'registration successful'});}
})(req, res, next);
},
function(err, req, res, next) {
return res.send({'status':'err','message':err.message});
});
And my passport strategy:
passport.use('local-registration', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
console.log('credentials passed to passport' + email + '' + password)
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, {message: 'User already exists'});
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
I dont think you should send "req" as a parameter to the authentication function. take a look at this example from the passport docs:
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));

Using PassportJS, how does one pass additional form fields to the local authentication strategy?

I'm using passportJS and I'm wanting to supply more than just req.body.username and req.body.password to my authentication strategy (passport-local).
I have 3 form fields: username, password, & foo
How do I go about accessing req.body.foo from my local strategy which looks like:
passport.use(new LocalStrategy(
{usernameField: 'email'},
function(email, password, done) {
User.findOne({ email: email }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Unknown user' });
}
if (password != 1212) {
return done(null, false, { message: 'Invalid password' });
}
console.log('I just wanna see foo! ' + req.body.foo); // this fails!
return done(null, user, aToken);
});
}
));
I'm calling this inside my route (not as route middleware) like so:
app.post('/api/auth', function(req, res, next) {
passport.authenticate('local', {session:false}, function(err, user, token_record) {
if (err) { return next(err) }
res.json({access_token:token_record.access_token});
})(req, res, next);
});
There's a passReqToCallback option that you can enable, like so:
passport.use(new LocalStrategy(
{usernameField: 'email', passReqToCallback: true},
function(req, email, password, done) {
// now you can check req.body.foo
}
));
When, set req becomes the first argument to the verify callback, and you can inspect it as you wish.
In most common cases we need to provide 2 options for login
with email
with mobile
Its simple , we can take common filed username and query $or by two options , i posted following snippets,if some one have have same question .
We can also use 'passReqToCallback' is best option too , thanks #Jared Hanson
passport.use(new LocalStrategy({
usernameField: 'username', passReqToCallback: true
}, async (req, username, password, done) => {
try {
//find user with email or mobile
const user = await Users.findOne({ $or: [{ email: username }, { mobile: username }] });
//if not handle it
if (!user) {
return done(null, {
status: false,
message: "That e-mail address or mobile doesn't have an associated user account. Are you sure you've registered?"
});
}
//match password
const isMatch = await user.isValidPassword(password);
debugger
if (!isMatch) {
return done(null, {
status: false,
message: "Invalid username and password."
})
}
//otherwise return user
done(null, {
status: true,
data: user
});
} catch (error) {
done(error, {
status: false,
message: error
});
}
}));

Resources