I have a field called mail as unique in MongoDB.
I'm trying to update the user but it happens that if I don't change the mail field it tells me it's a duplicate. I need it not to be necessary to always change the email because sometimes they just want to change another field.
This is my model:
import { Schema, model } from "mongoose";
const UserSchema = Schema (
{
username: {
type: String,
maxlength:50,
required: [true, 'El Nombre de Usuario es obligatorio'],
unique: true
},
name: {
type: String,
maxlength:50,
required: [true, 'El Nombre es obligatorio']
},
lastName: {
type: String,
maxlength:50,
required: [true, 'El Apellido es obligatorio']
},
mail: {
type: String,
required: [true, 'El Correo es obligatorio'],
unique: true
},
password: {
type: String,
required: [true, 'La Contraseña es obligatorio']
},
picture:{
path: {
type: String
},
originalName: {
type: String
}
},
role: {
type: String,
required: true,
enum: ['ADMIN_ROLE', 'USER_ROLE', 'SUPER_ROLE', 'SELLER_ROLE', 'WAREHOUSE_ROLE', 'WAREHOUSE_ASSISTANT_ROLE', 'SALES_ROLE', 'PURCHASES_ROLE','CASH_ROLE']
},
status: {
type: Boolean,
default: true
},
createdBy:{
uid : { type: String, required: true },
username:{ type: String, required: true }
},
createdAt: {
type: Date,
default: Date.now
}
}
);
module.exports = model('Users', UserSchema);
This is my function where I update but it returns the error of duplicate key in mail.
const updateUser = async (req, res = response) => {
let id = req.params.id;
let { _id, password, ...data } = req.body;
if ( password ) {
let salt = bcrypt.genSaltSync(15);
resto.password = bcrypt.hashSync( password, salt );
}
let lastModificationByUser = {
uid: req.uid,
username: req.user.username,
comments: data.comments
};
let user = await User.findByIdAndUpdate( id,
{
$set: data,
$push: {
'lastModificationBy': {
$each: [lastModificationByUser],
$slice: -5
}
}
},{ new: true }
);
res.json({
user
})
}
But I get the following error:
Thanks for your help.
CodePudding user response:
Understand unique
if you create a user with a unique email address and then update their email address to a non-unique value (same email address), you'll get the dup key error.
if you insert a user with the email address empty, and you try to create another user with the email address empty, you will also get the dup error.
In your case
Remove the mail
field from your data
object, unless you are updating the user with a new unique email address.
DO NOT TRUST ANYTHING SUBMITTED CLIENT SIDE
let { _id, password, ...data } = req.body;
Destructuring and then updating the data
field directly to the model is not safe. (e.g. even if your form does not contain the password field)
For example, I can send a post request with curl
or postman
with the password
field, and you will be updating the password too without knowing.
What you should do
const { name, lastname, picture } = data;
const update = { name, lastname, picture }
let user = await User.findByIdAndUpdate( id, update );
PS: this is just an example, though in your codes you already conditionally check your password.