I'm trying to get my login component on the server side to work, but it keeps giving me this one error over and over. "TypeError: User.comparePassword is not a function" I had it working in postman before, but I can't figure out why it broke now. I'm making an ecommerce site, so I'm excluding code that has stuff to do with the rest of the site.
[user.js - my routing and where the error is being presented.]
const { User, validateUser } = require("../models/user.js");
const bcrypt = require("bcrypt");
const config = require("config");
const jwt = require("jsonwebtoken");
const auth = require("../middleware/auth");
const express = require("express");
const router = express.Router();
//get users
router.get("/", async (req, res) => {
try {
const users = await User.find();
return res.send(users);
} catch (ex) {
return res.status(500).send(`Internal server Error: ${ex}`);
}
});
//get a user
router.get("/:userId", async (req, res) => {
try {
const user = await User.findById(req.params.userId);
return res.send(user);
} catch (ex) {
return res.status(500).send(`Internal server Error: ${ex}`);
}
});
//new user
router.post("/register", async (req, res) => {
try {
const { error } = validateUser(req.body);
if (error) return res.status(500).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (user) return res.status(400).send("User already registered.");
const salt = await bcrypt.genSalt(10);
user = new User({
name: req.body.name,
email: req.body.email,
password: await bcrypt.hash(req.body.password, salt),
});
await user.save();
const token = jwt.sign(
{ _id: user._id, name: user.name },
config.get("jwtSecret")
);
return res
.header("x-auth-token", token)
.header("access-control-expose-headers", "x-auth-token")
.send({ _id: user._id, name: user.name, email: user.email });
} catch (ex) {
return res.status(500).send(`InternalServerError:${ex}`);
}
});
router.get("/auth", auth, (req, res) => {
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
isAuth: true,
email: req.user.email,
name: req.user.name,
role: req.user.role,
image: req.user.image,
cart: req.user.cart,
history: req.user.history,
});
});
router.post("/login", (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if (!User)
return res.json({
loginSuccess: false,
message: "Auth failed, email not found",
});
});
User.comparePassword(req.body.password, (err, isMatch) => {
if (!isMatch)
return res.json({ loginSuccess: false, message: "Wrong password" });
user.generateToken((err, user) => {
if (err) return res.status(400).send(err);
res.cookie("w_authExp", User.tokenExp);
res.cookie("w_auth", User.token).status(200).json({
loginSuccess: true,
userId: user._id,
});
});
});
router.get("/logout", auth, (req, res) => {
User.findOneAndUpdate(
{ _id: req.user._id },
{ token: "", tokenExp: "" },
(err, doc) => {
if (err) return res.json({ success: false, err });
return res.status(200).send({
success: true,
});
}
);
});
});
[User.js - Userschema]
const mongoose = require('mongoose');
const Joi = require('joi');
const cors = require('cors');
const config = require('config');
const jwt = require('jsonwebtoken');
const { productSchema } = require('./Product');
const { reviewSchema } = require('./review');
const userSchema = new mongoose.Schema({
name: { type: String, required: true, minlength: 5, maxlength: 50},
email: {type: String, unique: true, required: true, minlength: 5, maxlength: 255},
password: {type: String, required: true, maxlength: 1024, minlength: 5},
timestamp: { type: Date, default: Date.now() },
cart: {type: [productSchema], default: []},
newSalePost: {type: [productSchema], default: []},
review: {type: [reviewSchema], default: []},
image: {type: String, required: true}
});
const User = mongoose.model('User', userSchema);
userSchema.methods.generateAuthToken = function () {
return jwt.sign({_id: this._id, name: this.name, isAdmin: this.isAdmin}, config.get('jwtSecret'));
};
function validateUser(user){
const schema = Joi.object({
name: Joi.string().min(5).max(50).required(),
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(5).max(1024).required(),
});
return schema.validate(user);
}
userSchema.statics.findByToken = function (token, cb) {
var user = this;
jwt.verify(token, 'secret', function (err, decode) {
user.findOne({ "_id": decode, "token": token }, function (err, user) {
if (err) return cb(err);
cb(null, user);
})
})
}
exports.User = User;
exports.validateUser = validateUser;
exports.userSchema = userSchema;