yöntem bir işlev değildir Mongoose yöntemleri sorunu

Jan 03 2021

ENV:

düğüm v12.19.0

mongo Atlas V4.2.11

firavun faresi V5.11.8

#################################################

Kullanıcı Şemam var

user.js

const mongoose = require('mongoose');
const bcrypt   = require('bcrypt');

const userSchema = new mongoose.Schema({
    email:{
        type: String,
        required: true,
        unique: true, 
    },
    username:{
        type: String,
        required: true,
        unique: true,
    },
    password:{
        type: String,
        required: true
    },
    profileImageUrl:{
        type: String,
    }
});

userSchema.pre('save', async function(next) {
    try{
        if(!this.isModified('password')){
            return next();
        }

        let hashedPassword = await bcrypt.hash(this.password, 10);
        this.password = hashedPassword;
        return next();

    } catch(err) {
        return next(err);
    }
});

userSchema.methods.comparePassword = async function(candidatePassword){
    try{
        return await bcrypt.compare(candidatePassword, this.password);

    } catch(err){
        throw new Error(err.message);
    }
}

userSchema.set('timestamps', true);

module.exports = mongoose.model("User", userSchema);

Parolanın değiştirilip değiştirilmediğini kontrol ediyorum, ardından kaydetmeden önce değiştiriyorum.

ve parola ile karşılaştırmaPassword adında bir karma parolayı karşılaştırmak için bir yöntem ekledim

ComparePassword yöntemini başka bir dosyada kullanmaya çalışıyorum

Auth.js


const db = require('../models');
const JWT = require("jsonwebtoken");
const CONFIGS = require('../config');

exports.signIn = async function(req, res, next){
    try{

        const user = db.User.findOne({
            email: req.body.email,
        });

        const { id, username, profileImageUrl } = user;
        const isMatch = await user.comparePassword(req.body.password) ; // here is a problem <====

        if(isMatch){
            const token = JWT.sign({
                id,
                username,
                profileImageUrl,
            }, CONFIGS.SECRET_KEY);
            return res.status(200).json({
                id,
                username,
                profileImageUrl,
                token,
            });
        }
        else{
            return next({
                status: 400,
                message: "Invalid email or password",
            });
        }
    }
    catch(err){
        return next(err);
    }
}
   

Parolaları önceden tanımlanmış yöntemle karşılaştırmaya çalıştığımda, yanıtta bunu döndürüyor

user.comparePassword bir işlev değil

Çeşitli çözümlere baktım.

bazıları bunun kendileri için işe yaradığını söyledi:

userSchema.method('comparePassword' , async function(candidatePassword, next){
  // the logic
})

ama işe yaramıyor farklı çözümler de denedim ama kodda neyin yanlış olduğundan emin değilim.

Güncelleme 1:

Statiği kullanmayı denedim ve işe yaramıyor

userSchema.statics.comparePassword = async function(candidatePassword){
    try{
        return await bcrypt.compare(candidatePassword, this.password);

    } catch(err){
        throw new Error(err.message);
    }
}

Yanıtlar

AhmedGaafer Jan 04 2021 at 01:12

In Auth.js

 const user = db.User.findOne({
            email: req.body.email,
        });

bu yanlış çünkü sorgunun bitmesini beklemeliyiz;

böyle olmalı

 const user = await db.User.findOne({
            email: req.body.email,
        });