Mon goose .findOne не является функцией - используется паспорт - PullRequest
0 голосов
/ 14 января 2020

Я получаю эту ошибку, пытаясь использовать мою локальную стратегию по паспорту lib.

TypeError: UserModel.findOne is not a function

Я часами осматривался, но, похоже, не могу найти решение, которое подходит для моей проблемы. Вот мои файлы user.model и auth.services.

user.model

const mongoose = require('mongoose');
const validator = require('validator');
const uniqueValidator = require('mongoose-unique-validator');
const jwt = require('jsonwebtoken');

const cryptor = require('../services/bcrypt.services');
const authServices = require('../services/auth.services');

const Schema = mongoose.Schema;

const UserSchema = new Schema({

    email: {
        type: String,
        unique: true,
        trim: true,
        lowercase: true,
        required: [true, 'Email is required'],
        validate: {
            validator: function(email) {
                return validator.isEmail(email);
            },
            message: function (props) { `${props.value} is not an valid email` }
        }
    },
    password: {
        type: String,
        trim: true,
        minlength: [6, 'Password too short'],
        lowercase: true,
        required: true
    },

    conversations: [{ type: Schema.Types.ObjectID, ref: 'Conversation' }]
});

UserSchema.methods = {

    async _hashPassword(password) {
        this.password = await cryptor.hashAsync(password);
    },

    async authUser(password) {
        return await cryptor.compareAsync(password, this.password);
    },

    createToken() {
        return jwt.sign({
            _id: this._id
        }, authServices.privateKey);
    },

    toAuthJWT() {
        return {
            _id: this._id,
            email: this.email,
            token: this.createToken()
        };
    },

    toJSON() {
        return {
            _id: this._id,
            email: this.email
        }
    }

};

UserSchema.pre('save', async function (next) {
    if (this.isModified('password')) {
        this._hashPassword(this.password);
    }

    next();
});

UserSchema.plugin(uniqueValidator, { message: '{VALUE} already exists' });

module.exports = mongoose.model('User', UserSchema);

auth.services

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const JWTStrategy = require('passport-jwt').Strategy;
const ExtractJWT = require('passport-jwt').ExtractJwt;
const UserModel = require('../user/user.model');
const fs = require('fs');



// LocalStrategy
let localStrategy = new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(email, password, done) {

    UserModel.findOne({ email: email }, function(err, user) {
        if (err) {
            return done(err);
        } else if(!user) {
            // Invalid email
            return done(null, false);
        } else if(!user.authUser(password)) {
            // Invalid password
            return done(null, false);
        }

        return done(null, user);
    });
});

passport.use(localStrategy);


// JWTStrategy
// eslint-disable-next-line no-undef
const privateKEY = fs.readFileSync(__dirname + '/private.key', 'utf8');
// eslint-disable-next-line no-undef
const publicKEY = fs.readFileSync(__dirname + '/public.key', 'utf8');

let jwtStrategy = new JWTStrategy({
    jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),
    secretOrKey: publicKEY
}, function(payload, done) {

    UserModel.findById(payload._id, function(err, user) {
        if (err) {
            return done(err);
        } else if(!user) {
            return done(null, false);
        }

        return done(null, user);
    });

});

passport.use(jwtStrategy);

module.exports = {
    authLocal: passport.authenticate('local', { session: false }),
    authJwt: passport.authenticate('jwt', { session: false }),
    privateKey: privateKEY
};

Я не понимаю, почему он не может найти функцию UserModel.findOne, или, может быть, я что-то упустил.

Ответы [ 2 ]

1 голос
/ 15 января 2020

Решил это. Проблема была с программным потоком. Я использовал auth.services в моем файле user.model, чтобы завладеть моим privateKey. Это заставило меня пытаться использовать мою модель еще до ее инициализации.

1 голос
/ 14 января 2020

В вашей схеме вы не расширяете существующих методов, вы полностью перезаписываете их, т.е.

UserSchema.methods = { ... }

Эта строка назначает новый объект для methods, который полностью уничтожает любые существующие функции (например, findOne), которые обеспечивает Mon goose. Если вы хотите добавить в схему функции stati c, вы можете расширить statics

UserSchema.statics.myFunction = () => { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...