findByIdAndUpdate not updating document on MongoDB - mongodb

I am trying to create an Api that updates my MongoDB before sending a password reset email to the user using nodemailer. Everything works fine except the database update for some reason. I am using findByIdAndUpdate to do the update.
My api starts with
router.put('/forgot',[auth, [check('email', 'Please include a valid email').isEmail()]],async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email } = req.body;
try {
let user = await User.findOne({ email });
if (!user) {
return res.status(400).json({
errors: [
{
msg:
'That email addrss is not recognized. Please try again or register for a new account ',
},
],
});
}
var email_token = crypto.randomBytes(64).toString('hex');
const payload = {
id: user.id,
resetPasswordToken: email_token,
resetPasswordExpires: Date.now() + 3600000,
};
user = await User.findByIdAndUpdate(
user.id,
{ $set: payload },
{ new: true }
);
console.log(user);
res.json(user);

Thank you Joe and Mohammed, Well from Mohammed question i realized i did not define resetPasswordToken and resetPasswordExpires in the User Model. As soon as i did that every thing worked as magic. Thank you so much!

Related

Mongo DB .findOne returning null value. This also lead to my login not working

My current login route function that use findOne. Currently using findOne with a email being used to searched for inside my database. But since my user always return null my feedback is always Invalid credentials.
const login = asyncHandler(async (req, res) => {
const { email, password } = req.body
// Check for user email
const user = await Staff.findOne({email})
console.log(user);
if (user && (await bcrypt.compare(password, user.password))) {
res.json({
_id: user.id,
name: user.name,
email: user.email,
})
} else {
res.status(400)
throw new Error('Invalid credentials')
}
})

Why is MongoDB not saving my user (issues with async/await?) - Express, mongoDB, Oauth

I'm using Oauth to allow my users to sign in with their google account. I have successfully created a function which checks if the email is verified and then, depending on if the user is already saved in the data base, just send back the user - or if the user doesn't exsist create a new user.
My console displays the message "Email is verified" and "User not found" so I know it makes it to that part of the code - but it doesn't proceed to create a new user. My suspicions is that is has to do with the async await and that things are perhaps happening in the wrong order. Any thoughts would be much appreciated!
app.post("/googlelogin", (req, res) => {
const { tokenId } = req.body
client.verifyIdToken({
idToken: tokenId,
audience: 'XXXX' // removed for demo
})
.then(async (response) => {
const { email_verified, name, email } = response.payload
console.log(response.payload)
if (email_verified) {
console.log('email is verified')
try {
const user = await User.findOne({ name, email })
if (user) {
console.log('User found!')
return res.json({
success: true,
name: user.name,
email: user.email,
token: user.token,
userID: user._id
})
} else {
console.log('User not found!')
let newUser = await new User({
name,
email
}).save()
return res.json({
success: true,
name: newUser.name,
email: newUser.email,
token: newUser.token,
userID: newUser._id
})
}
} catch (error) {
res.status(400).json({
success: false,
message: "Something went wrong",
error
})
}
} else {
return res.status(400).json({
success: false,
error: "Email not verified",
})
}
})
})
SOLVED.
Found this thread and followed the tip to drop my collection and after this it worked!
MongoError: E11000 duplicate key error collection: tracker-db.users index: username_1 dup key: { username: null }"

axios request not going through to backend

I'm struggling getting this axios call to work. It's in a password reset feature, and it calls an axios request that sends through to the back end, but it's just coming up with an error instead of executing the code in the router route.
I call the request in this block here.
front end side:
async componentDidMount() {
const {
match: {
params: { token },
},
} = this.props;
try {
const response = await axios.get('http://localhost:5000/api/users/reset', {
params: {
resetPasswordToken: token,
},
});
console.log(response)
if (response.data.message === 'password reset link a-ok') {
this.setState({
username: response.data.username,
updated: false,
isLoading: false,
error: false,
});
}
} catch (error) {
console.log(error.response.data);
this.setState({
updated: false,
isLoading: false,
error: true,
});
}
}
It's getting the proper token and everything, but the http://localhost:5000/api/users/reset should be pointing to the /reset route in the code below, and it's never reached.
const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const keys = require("../../config/keys");
const validateRegisterInput = require("../../validation/register");
const validateLoginInput = require("../../validation/login");
const nodemailer = require('nodemailer');
const crypto = require('crypto');
require('dotenv').config();
const User = require("../../models/User");
router.route('/reset').get((req, res, next) => {
User.find({
where: {resetPasswordToken: req.query.resetPasswordToken,
resetPasswordExpires: {
$gt: Date.now(),
},
},
}).then(user => {
if(user == null) {
console.log('password reset link is invalid or has expired');
res.json('password reset link is invalid or has expired');
}else{
res.status(200).send({
username: user.username,
message: 'password reset link a-ok',
});
}
});
});
module.exports = router;
Actually #TamasSzoke you led me to answer my own question so I thank you! I had another route that was just /:id and that's what it was trying to validate there.
Just have to change that one up and it'll be all good.
thank you!!!

Fail to save user to mongodb

If I remain this code, the program still working, my image will upload backend to frontend normally
router.post('/admin/register', upload.single('avatar'), async (req, res) => {
// Handle add image by multer
... handel file upload from front-end
return res.json({ avatar: newFullPath });
}
);
I started save user to mongoDB and error occur
router.post('/admin/register', upload.single('avatar'), async (req, res) => {
// Handle add image by multer
... handel file upload from front-end
//Handle add user to database
const user = {
...JSON.parse(req.body.user),
avatar: newFullPath
}; // { first_name: 'John', last_name: 'Wick', avatar: .... }
const { error } = Validation.adminRegisterValidation(user);
if (error) {
return res.json({ error: error.details[0].message });
} // working as I expected
const emailExist = await User.findOne({ email: user.email });
if (emailExist) {
return res.json({ error: 'Email already exist!' });
} // working as I expected
// If I commented this block of code, program still run as I expected, but if I don't do
// that, the program crashed ( Error: Below images )
const hashedPassword = bcrypt.hashSync(user.password, 10);
const addUser = new User({
first_name: user.first_name,
last_name: user.last_name,
avatar: user.avatar
});
await addUser.save();
return res.json({ avatar: newFullPath });
}
);
This project in my Github repository: This project in Github
Error shows in console
Error in Network

Getting email with mongoose, always undefined

I'm using mongoose in my nodejs/express project.
I have a login form and I want to retrieve the email field, but I always get a "undefined" value.
This is my code:
User.findOne({ email: email, pass: pass }, function(err, user_data){
if (err) return handleError(err);
if(user_data){
req.session.user_id = user_data._id;
req.session.email = user_data.email;
console.log(user_data);
console.log("the email: " + user_data.email);
console.log("the name: " + user_data.name);
res.redirect('/');
}else{
res.redirect('/login');
}
});
The output:
{ _id: 534038aca4198a8fcf0001ac,
name: 'My name',
email: 'myemail#gmail.com',
pass: '098f6bcd4621d373cade4e832627b4f6' }
The email: undefined
The name: My name
What is wrong with the email field ?
Thanks
I had the same error and i solve creating a new object from the response of the mongoose query.
exports.getUser = async (req, res) => {
try {
const user = await User.findOne({email: email, pass: pass})
const userParams = {...user}
const email = userParams._doc.email
console.log(email)
} catch(err) {
console.log(err)
}
}
I don't recommend you to use this method to auth users, please check auth0 or Oauth2.