La méthode n'est pas une fonction Problème de méthodes de mangouste

Jan 03 2021

ENV:

nœud v12.19.0

mongo Atlas V4.2.11

mangouste V5.11.8

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

J'ai un schéma utilisateur

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);

Je vérifie si le mot de passe n'est pas modifié puis je le modifie avant l'enregistrement.

et j'ai ajouté une méthode pour comparer le mot de passe avec un mot de passe haché appelé comparePassword

J'essaye d'utiliser la méthode comparePassword dans un autre fichier

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);
    }
}
   

quand j'essaye de comparer les mots de passe avec la méthode prédéfinie, cela renvoie ceci dans la réponse

user.comparePassword n'est pas une fonction

J'ai examiné diverses solutions.

certains ont dit que cela fonctionne pour eux:

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

mais cela ne fonctionne pas. J'ai aussi essayé différentes solutions mais je ne suis pas sûr de ce qui ne va pas avec le code.

Mise à jour 1:

J'ai essayé d'utiliser la statique et cela ne fonctionne pas

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

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

Réponses

AhmedGaafer Jan 04 2021 at 01:12

Dans Auth.js

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

c'est faux car nous devons attendre la fin de la requête;

ça devrait être comme ça

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