Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

183
Visualizações
Problem implementing password reset functionality (stopping users from using old passwords) - MongoDB & NodeJS

I am implementing auth for a web app and want to implement forgot/reset password functionality, and the user is not supposed to enter old used passwords when resetting their password. My specific question is this:

I have 1 mongoose user model that looks like this:

const UserSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
    select: false,
  },
  passwordChangedAt: {
    type: Date,
    required: false,
    default: null,
  },
  role: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Role',
    required: true,
  },
  ...Base,
});

I also have one password reset model:

const PasswordResetSchema = new mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true,
  },
  token: {
    type: String,
    required: true,
  },
  isUsed: {
    type: Boolean,
    required: false,
    default: false,
  },
  expireDate: {
    type: Date,
    required: true,
  },
  oldPassword: {
    type: String,
    required: true,
  },
  newPassword: {
    type: String,
    required: false,
    default: null,
  },
  ...Base,
});

Now when resetting the password I want to lookup in the password reset tables, and check if oldPassword or newPassword was already used before, and if it was used show an error to the user that they already once used that password.I use bcrypt to hash the password using a salt, which means that the same password can have a different hash in the database. So the problem is when querying the password reset collection, for same passwords use before, is there a way to query the passwords while comparing hashes and new plaintext password to check if the password was used.

  const hashedPassword = await bcrypt.hash(password, bcrypt.genSaltSync());
  // Here the hashedPassword is different, since the salt is different

  const usedSamePassPreviously = await PasswordReset.find({
    _id: { $nin: [passwordReset._id] },
    user: user._id,
    $or: [{ oldPassword: hashedPassword }, { newPassword: hashedPassword }],
    isUsed: true,
  });

I also tried querying using the $where clause in mongo, which allows me to use pure JavaScript function, but there we dont have access to bcrypt.compare function. I dont want to load all data in back-end and then find if a password was used, or use the same salt for all passwords since that is a security problem. How can i approach this query and is it possible to achieve this in the database side. Thanks in advance.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

You'll need to iterate over the hashes of all your forbidden passwords and use bcrypt's .compare() method on each one. That way you can see whether the new password value presented to you by your user should be rejected as a duplicate.

Do this in your client code.

It's true that doing .compare() takes time; that's a design feature. That's a reason you should not do it in your database server: the database is a shared resource and you don't want to do cpu-intensive long running operations there; they'll take CPU needed to serve other database client code. Do those operations in your nodejs code. If the performance is really a problem, consider using a worker thread.

And, consider the information security implication: To do this in your database you must send it the secret plaintext password presented to you by your user. You should avoid sending secrets anywhere they're not absolutely needed. Database software is large and complex, and presents a large attack surface to cybercreeps. So sending it secrets it doesn't need makes those secrets just a little more vulnerable. That's true even if you don't actually store the secrets.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda