when the answer is always found - javascript

why is the console output is always found? any email or passwords i enter, the output is the same, even if they are not in the database
app.post("/login", (req, res) => {
const email = req.body.username
const password = req.body.password
User.find({ email: email, password: password }, function(err, userInfo) {
if (err) {
console.log("err")
} else {
if (userInfo) {
console.log("found")
} else {
console.log("not found")
}
}
});
})

Because User.find will return an array, even if there is no document matching your query it will return an empty array.
And in javascript, if you pass empty array in if the condition it passes
Use User.findOne or check if (userInfo.length > 0)
app.post("/login", (req, res) => {
const email = req.body.username
const password = req.body.password
User.findOne({ email: email, password: password }, function(err, userInfo) {
if (err) {
console.log("err")
} else {
if (userInfo) {
console.log("found")
} else {
console.log("not found")
}
}
});
})

Related

Implementation of bcrypt/async gives query-result of undefined

The mysql query always returns undefined and I don't know whats wrongs. It used to work before I added the async await to the functions but that used to return an error in the terminal because bcrypt is an async function. Could someone help me with this? Here is my code
app.post('/login', async function(req, res) {
let username = req.body.username;
let password = req.body.password;
if (username && password) {
connection.query('SELECT username, password, email FROM accounts WHERE username = ?', [username], async function(err, result, fields) {
if (result.length > 0) {
try {
if(await bcrypt.compare(password, result.password)) {
req.session.loggedin = true;
req.session.username = username;
res.redirect('/');
}
else {
res.send('Incorrect Username and/or Password!');
}
}
catch (err) {
//res.status(500).send();
res.send('Something wrong happened');
console.log(err);
}
} else {
res.send('Incorrect Username and/or Password!');
}
res.end();
});
} else {
res.send('Please enter Username and Password!');
res.end();
}
});

How do I logout with JWT, passport Authentication (NodeJS)?

I am new to NodeJS and I have been following a tutorial. I made some changes to the tutorial code in order to allow users to login by typing in their username or email instead of just username.
passport.use(
new LocalStrategy(
(username_or_email, password, done) => {
User.findOne({ email: username_or_email }, (err, user) => {
if (err) {
return done(err);
console.log(err);
}
if (!user) {
User.findOne({ username: username_or_email }, (err, user) => {
//If there is an error
if (err) {
return done(err);
console.log(err);
}
//If there is no user
if (!user) {
return done(null, false);
} else {
user.comparePassword(password, done);
}
});
} else {
user.comparePassword(password, done);
}
});
}
)
The code above works well and allows users to type in username OR password to login.
Now when I follow the tutorial for how to logout, their method doesn't work for me.
I have a route like this, it is supposed to log a user out.
userRouter.get(
'/logout',
passport.authenticate('jwt', { session: false }),
(req, res) => {
res.clearCookie('access_token');
res.json({ user: { username: '', role: '' }, success: true });
}
);
When I go to it in Postman it says "Unauthorized" and does not return anything else.
I believe it could be something to do with my 'jwt' set up, shown below.
passport.use(
new JwtStrategy(
{
jwtFromRequest: cookieExtractor,
secretOrKey: 'NoobCoder',
},
(payload, done) => {
console.log(payload);
User.findById({ _id: payload.sub }, (err, user) => {
if (err) {
return done(err, false);
console.log('1');
}
if (user) {
return done(null, user);
console.log('2');
} else {
return done(null, false);
console.log('3');
}
});
}
)
);
This is the cookieExtractor function that I use for jwtFromRequest
const cookieExtractor = (req) => {
let token = null;
console.log(token);
if (req && req.cookies) {
token = req.cookies['access_token'];
}
return token;
};
The only console output I get is the console.log in the cookieExtractor.
Which makes me believe that that must be the point of failure. It is a "null" output as expected, and if I console.log the token, I get the current logged in users token. I believe the jwtFromRequest calls the cookieExtractor function but fails at some point soon after.

NodeJs :- Getting "missing credentials" error while using local passport

I was trying to implement a functionality where a user can reset a password. I have tried the below code and while I am not getting any error, its not updating the password. The password is the same ie the old password.
my User model file is as follows:-
const mongoose = require('mongoose');
var passportLocalMongoose = require("passport-local-mongoose");
const LoginUserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
resetPasswordToken: String,
resetPasswordExpires: Date
});
// The below is used so as to allow passport to reset password
LoginUserSchema.plugin(passportLocalMongoose);
const LoginUser = mongoose.model('LoginUser', LoginUserSchema);
module.exports = LoginUser;
My routes file is as follows:-
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
var async = require("async");
// Load User model
const User = require('../models/loginuser');
var nodemailer = require("nodemailer");
var crypto = require("crypto");
// Load Auth from files
const { ensureAuthenticated, forwardAuthenticated } = require('../config/auth');
// Login Page
router.get('/login', forwardAuthenticated, (req, res) => res.render('login'));
// Register Page
router.get('/register', (req, res) =>{
if(typeof req.user == "undefined"){
console.log("HERE IT IS");
res.redirect('/users/login');
}
if (req.user.email == "theamarex#gmail.com"){
res.render('register')
}else{
res.redirect('/users/login');
}
})
// Register
router.post('/register', (req, res) => {
const { name, email, password, password2 } = req.body;
let errors = [];
if (!name || !email || !password || !password2) {
errors.push({ msg: 'Please enter all fields' });
}
if (password != password2) {
errors.push({ msg: 'Passwords do not match' });
}
if (password.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters' });
}
if (errors.length > 0) {
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
User.findOne({ email: email }).then(user => {
if (user) {
errors.push({ msg: 'Email already exists' });
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
const newUser = new User({
name,
email,
password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => {
req.flash(
'success_msg',
'You are now registered and can log in'
);
res.redirect('/users/login');
})
.catch(err => console.log(err));
});
});
}
});
}
});
// Login
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/users/dashboard',
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
// Logout
router.get('/logout', (req, res) => {
req.logout();
req.flash('success_msg', 'You are logged out');
res.redirect('/users/login');
});
// Dashboard
router.get('/dashboard', ensureAuthenticated, (req, res) =>{
res.render('dashboard', {
user: req.user
})
}
);
// Forgot password url
router.get('/forgot', function(req, res) {
res.render('forgot');
});
router.post('/forgot', function(req, res, next) {
async.waterfall([
function(done) {
crypto.randomBytes(20, function(err, buf) {
var token = buf.toString('hex');
done(err, token);
});
},
function(token, done) {
User.findOne({ email: req.body.email }, function(err, user) {
if (!user) {
req.flash('error', 'No account with that email address exists.');
return res.redirect('/users/forgot');
}
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
user.save(function(err) {
done(err, token, user);
});
});
},
function(token, user, done) {
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: '',
pass: ''
}
});
var mailOptions = {
//to: user.email,
to: "cechque#gmail.com",
from: 'theamarexrouting#gmail.com',
subject: 'Node.js Password Reset',
text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
'http://' + req.headers.host + '/users/reset/' + token + '\n\n' +
'If you did not request this, please ignore this email and your password will remain unchanged.\n'
};
smtpTransport.sendMail(mailOptions, function(err) {
console.log('mail sent');
req.flash('success', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
done(err, 'done');
});
}
], function(err) {
if (err) return next(err);
res.redirect('/users/forgot');
});
});
// Reset password url
router.get('/reset/:token', function(req, res) {
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
if (!user) {
req.flash('error', 'Password reset token is invalid or has expired.');
return res.redirect('/forgot');
}
res.render('reset', {token: req.params.token});
});
});
router.post('/reset/:token', function(req, res) {
async.waterfall([
function(done) {
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
if (!user) {
req.flash('error', 'Password reset token is invalid or has expired.');
return res.redirect('back');
}
if(req.body.password === req.body.confirm) {
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
user.password = req.body.password;
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(user.password, salt, (err, hash) => {
if (err) throw err;
user.password = hash;
user.save(function(err) {
req.login(user, function(err) {
console.log(user);
done(err, user);
});
});
});
});
} else {
req.flash("error", "Passwords do not match.");
return res.redirect('back');
}
});
},
function(user, done) {
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: '',
pass: ''
}
});
var mailOptions = {
to: "",
from: '',
subject: 'Your password has been changed',
text: 'Hello,\n\n' +
'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n'
};
smtpTransport.sendMail(mailOptions, function(err) {
req.flash('success', 'Success! Your password has been changed.');
done(err);
});
}
], function(err) {
res.redirect('/users/dashboard');
});
});
module.exports = router;
I am a bit confused where I have gone wrong. I tried to search various answers online and on this forum but it didn't help me out. Please help me out. Thanks
I have made changes to the code. You have used passport-local-mongoose wrongly here.
//register
if (errors.length > 0) {
res.render('register', {
errors,
name,
username,
password,
password2
});
} else {
User.findOne({ username: username }).then(user => {
if (user) {
errors.push({ msg: 'username already exists' });
res.render('register', {
errors,
name,
username,
password,
password2
});
} else {
const newUser = new User({
name,
username,
password
});
User.register(newUser, req.body.password, function(err, user){
console.log(req.body)
if(err){
console.log(err);
return res.render("register", {error: err.message});
}
passport.authenticate("local")(req, res, function(){
req.flash("success", "Successfully Signed Up! Nice to meet you " + req.body.name);
res.redirect('/users/login');
});
});
}
});
}
// forgot password
router.post('/forgot', function(req, res, next) {
async.waterfall([
function(done) {
crypto.randomBytes(20, function(err, buf) {
var token = buf.toString('hex');
done(err, token);
});
},
function(token, done) {
User.findOne({ username: req.body.username }, function(err, user) {
if (!user) {
req.flash('error', 'No account with that username address exists.');
return res.redirect('/users/forgot');
}
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
user.save(function(err) {
done(err, token, user);
});
});
},
//reset token
async.waterfall([
function(done) {
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
if (!user) {
req.flash('error', 'Password reset token is invalid or has expired.');
return res.redirect('back');
}
if(req.body.password === req.body.confirm) {
user.setPassword(req.body.password, function(err) {
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
user.save(function(err) {
req.logIn(user, function(err) {
done(err, user);
});
});
})
} else {
req.flash("error", "Passwords do not match.");
return res.redirect('back');
}
});
},
I got a changepassword route using passport. Maybe its useful for you. Here it is:
router.post('/changepassword', passport.authenticate('jwt', { session: false }), (req, res) => {
User.findOne({ username: req.user.username })
.then(user => {
if (!user) {
return res.status(404).json({
success: false
});
} else if (req.body.password !== req.body.confirm_password) {
return res.status(404).json({
msg: "Wachtwoorden komen niet overeen",
success: false
});
}
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(req.body.password, salt, (err, hash) => {
user.password = hash;
user.save().then(user => {
return res.status(201).json({
success: true,
msg: "Wachtwoord veranderd"
});
})
});
});
})
.catch(err => {
console.log(err)
})
})

My user registration data isn't passing to the login route

usersRouter.post('/register', checkNotAuthenticated, async (req, res) => {
console.log(req.body)
const salt = await bcrypt.genSalt();
const hashedPassword = await bcrypt.hash(req.body.password, salt);
const user = new User ({
name: req.body.name,
email: req.body.email,
password: hashedPassword
})
try {
await user.save();
res.redirect(201, '../users/login') /* 200 means accepted status, 201 created resource */
} catch {
res.redirect(500, 'users/register') /* Internal server error */
}
});
usersRouter.post('/login', async (req, res) => {
const user = await User.find({email: req.body.email})
console.log(user)
if (!user) {
return res.send('User does not exist')
}
try {
if (!await bcrypt.compare(req.body.password, user.password)) {
return res.status(401).send('password failed') /* user Unauthorized */
} else {
return res.status(200).send('password validated');
}
} catch (err) {
res.send(err.message)
}
})
In /register path
When I try to make a request, console.log(req.body) = [Object: null prototype] { name: 'p', email: 'p#p', password: '1' }
In /login path
console.log(user) = [], instead of the registered user
console.log(user.email) = undefined; instead of the registered user email

Bcrypt reset the hash and the passwords of the users are not good anymore each time the users POST data

I made a login with bcrypt.
I also made a page where users can edit their information, like their bio etc.
Each time an user edit his bio on this page the hash from bcrypt change, which is normal i suppose, but the user login back, the password is wrong...
I used the same model for mongoDb for the user when he log in and when he edit his data.
I started node.js recently so I apologize if my question is stupid,,,
The controller code with the Post :
app.post('/settings-user', mid.requiresLogin, function(req, res, next){
User.findById(req.session.userId, function (err, user) {
// todo: don't forget to handle err
if (!user) {
return res.redirect('/edit');
}
// good idea to trim
var bio = req.body.bio.trim();
// validate
if (!bio) { // simplified: '' is a falsey
req.flash('error', 'One or more fields are empty');
return res.redirect('/settings-user'); // modified
}
// no need for else since you are returning early ^
user.bio = bio;
// don't forget to save!
user.save(function (err) {
// todo: don't forget to handle err
res.redirect('/settings-user/');
});
});
});
The User model :
app.post('/settings-user', mid.requiresLogin, function(req, res, next){
User.findById(req.session.userId, function (err, user) {
// todo: don't forget to handle err
if (!user) {
return res.redirect('/edit');
}
// good idea to trim
var bio = req.body.bio.trim();
// validate
if (!bio) { // simplified: '' is a falsey
req.flash('error', 'One or more fields are empty');
return res.redirect('/settings-user'); // modified
}
// no need for else since you are returning early ^
user.bio = bio;
// don't forget to save!
user.save(function (err) {
// todo: don't forget to handle err
res.redirect('/settings-user/');
});
});
});
The User model :
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
var UserSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true,
trim: true
},
name: {
type: String,
required: true,
trim: true
},
password: {
type: String,
required: true
},
bio: {
type: String
}
});
// authenticate input against database documents
UserSchema.statics.authenticate = function(email, password, callback) {
User.findOne({ email: email })
.exec(function (error, user) {
if (error) {
return callback(error);
} else if ( !user ) {
var err = new Error('User not found.');
err.status = 401;
return callback(err);
}
bcrypt.compare(password, user.password , function(error, result) {
if (result === true) {
return callback(null, user);
} else {
return callback();
}
})
});
}
// hash password before saving to database
UserSchema.pre('save', function(next) {
var user = this;
bcrypt.hash(user.password, 10, function(err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
})
});
var User = mongoose.model('User', UserSchema);
module.exports = User;
the pug file :
div
form(method='post', action='/settings-user')
label ADD BIO
br
input(type='text', name='bio', placeholder='Enter something', required='')
input(type='submit', value='Add Bio')
</body>
If anyone could help,,,
thank you!

Categories