MongoDb + Mongoose | How to hash array of passwords instead of a single password

I have a json array containing data of almost 300 users. I am using (Mongoose)Model.InsertMany() for saving user data array to Mongodb. To hash a single user password i am using this guide: https://www.mongodb.com/blog/post/password-authentication-with-mongoose-part-1

but i want to hash passwords of all users at once. This guide uses 'save' function to hash but as i am using 'InsertMany()' to dump to Mongodb so how can i achieve hashing by using InsertMany()

Upvotes: 0

Views: 1181

Answers (4)

Elijah Romer
Elijah Romer

Reputation: 33

Here's how I managed to pull it off, being that Mongoose pre-hooks don't fire when insertMany() is called. Brought in the pre-hook functionality into the seed file, and looped through the data, hashing each password BEFORE passing it to insertMany.

  const bcrypt = require('bcrypt');
  const userData = require(`./userData.js`)
  const saltRounds = 10;

  const usersWithHashedPasswordsPromiseArray = userData.map(
    async (user) => {
      let hashedPassword = await bcrypt.hash(user.password, saltRounds);
      user.password = hashedPassword;
      return user;
  })

  const usersWithHashedPasswords = await Promise.all(usersWithHashedPasswordsPromiseArray)

  const users = await User.insertMany(usersWithHashedPasswords)

  console.log(users)
  console.log('users seeded');

Upvotes: 2

SuleymanSah
SuleymanSah

Reputation: 17858

You can use pre save hook in your user model.

The problem is InsertMany does not work with pre save hook.

But using Model.create will call any hooks declared on your schema.

So you can use User.create() method to make it work.

https://mongoosejs.com/docs/api/model.html#model_Model.create

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

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

userSchema.pre('save', async function(next) {
  this.password = await bcrypt.hash(this.password, 12);
  next();
});

const User = mongoose.model('User', userSchema);

module.exports = User;

Upvotes: 1

Kalpesh Kashyap
Kalpesh Kashyap

Reputation: 824

you have to create pre hooks on mongoose that will call before creating a document, in pre hook function you can use bcrypt a node library generate a hash string.

Upvotes: 0

Shihab
Shihab

Reputation: 2679

Mongoose insertMany() doesn't trigger the .save() hook. So, you should hash all the passwords first then use insertMany() function to insert them into database.

Upvotes: 0

Related Questions