I defined an instance method on one of my schemas(userSchema) called correctPassword which should compare a candidate password to the hashed password stored in the DB, but it is not recognised on the User model.
user.schema.ts:
const userSchema = new mongoose.Schema<IUser>({
name: {
type: String,
required: true,
trim: true
},
password: {
type: String,
required: true,
minlength: 8,
select: false,
},
email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true,
validate: validator.isEmail,
},
subscribers: {
type: Number,
default: 0,
}
})
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) {
return next()
}
this.password = await bcryptjs.hash(this.password, 12)
next()
})
userSchema.methods.correctPassword = async function(candidatePassword, userPassword) {
return await bcryptjs.compare(candidatePassword, userPassword)
};
export const User = mongoose.model<IUser>('User', userSchema)
When I try to call correctPassword on a User document the compiler says Property 'correctPassword' does not exist on type 'Document<unknown, {}, IUser> & IUser & { _id: ObjectId; }'.
The controller method:
public readonly login = async (req: Request, res: Response) => {
const { email, password } = req.body
if (!email || !password) {
return res.status(400).json({ message: 'Body must contain email and password' })
}
const user = await User.findOne({ email }).select('+password');
const passwordMatch = await user.correctPassword(password, user.password);
if (!user || !passwordMatch) {
return res.status(401).json({ message: 'Incorrect email or password' })
}
const token = this.signToken(user._id);
return res.status(200).json({ token });
}
I also tried defining the method directly in the schema options but faced the same issue.
I'm using Express 4.18.2, Mongoose 8.0.0