I am attempting to log a user in to my DB. When I log the user in, it returns the first userId in the DB and not the user who logged in. I have been struggling with this for a while and really am at a dead end.
This is my POST route to log the user in:
// login
router.post("/login", async (req, res) => {
const user = await User.findOne({
email: req.body.email,
});
const secret = process.env.SECRET;
if (!user) {
return res.status(400).send("the user not found!");
}
if (user && bcrypt.compareSync(req.body.password, user.passwordHash)) {
const token = jwt.sign(
{
userId: user.id,
isAdmin: user.isAdmin,
},
secret,
{ expiresIn: "1d" }
);
res.status(200).send({ user: user.email, token: token });
} else {
res.status(400).send("password is wrong!");
}
});
The const user = await User.findOne({ email: req.body.email, });
this returns the wrong user.
When I query the endpoint get a users profile with the userId
it gets the right information. So its got nothing to do with the DB.
This is the call in the app.
const handleSubmit = () => {
axios
.post(`${baseURL}users/login`, {
email: email,
passwordHash: password,
})
.then(res => {
console.log('USER ID TOKEN', res.data.token);
setbearerToken(res.data.token);
AsyncStorage.setItem('bearerToken', res.data.token);
const decoded = decode(res.data.token);
setTokenID(decoded.userId);
dispatch(setUser(res.data));
});
};
user.js model
const userSchema = mongoose.Schema({
contactName: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
phone: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
passwordHash: {
type: String,
required: true,
minlength: 5,
maxlength: 1024
},
token: {
type: String,
},
isAdmin: {
type: Boolean,
default: false
},
clubName: {
type: String,
required: true,
},
clubAddress: {
type: String,
required: true,
},
clubEmail: {
type: String,
required: true,
},
clubPhone: {
type: String,
required: true,
},
clubWebsite: {
type: String,
required: true,
},
clubContact: {
type: String,
required: true,
},
})
CodePudding user response:
Your schema doesn't have a field email
to filter on.
const user = await User.findOne({
email: req.body.email,
});
Maybe you try clubEmail
field. I reproduced the behavior and it looks like that mongoose ignores the filter if the field does not exist in the Schema an just returns the first document in the collection.
E.g.
const userSchema = new Schema(
{
name: String,
age: Number
}
)
const User = mongoose.model('User', userSchema);
User.findOne({name: "Superman"}, ...
Returns the user with name "Superman".
const userSchema = new Schema(
{
name: String,
age: Number
}
)
const User = mongoose.model('User', userSchema);
User.findOne({xname: "Superman"}, ...
But when using xname
in the filter document which does not exist in my schema neither in the collection as field the query returns the first document in my test collection (its not Superman).
Also look here similar issue: Model.find Mongoose 6.012 always return all documents even though having filter
Issue reported: https://github.com/Automattic/mongoose/issues/10763
Migration Guide to Mongoose 6: https://mongoosejs.com/docs/migrating_to_6.html#strictquery-is-removed-and-replaced-by-strict