TypeError: User.comparePassword is not a function. Comes up with Postman

Viewed 80

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;

0 Answers
Related