7

I have a schema that looks like this :

"use strict"

const mongoose = require('mongoose');
const timestamp  = require('mongoose-timestamp');

const CustomerSchema = new mongoose.Schema({
    name : {
        type : String,
        required : true,
        trim : true
    },
    email : {
        type : String,
        required : true,
        trim : true
    },
    balance : {
        type : Number ,
        default : 0
    }
})

//use timestamps to add created at and updated at
CustomerSchema.plugin(timestamp);

const Customer = mongoose.model('Customer',CustomerSchema);

module.exports = Customer;

When I want to run an update , I run this code

const Customer = require('../models/Customer');
const customer =  await Customer.findOneAndUpdate({_id : req.params.id}, req.body);

so req.body carries the data that will be updated The problem is that I do not want people to update the email field .

So my question is :

How do I lock the email field from being updated . Is there a way to lock it in the schema , so that it can only be added initially but not updated later ?

Thanks .

  • 1
    Well you could always simply deference in code. i.e `let { email, ...update } = req.body` Which would essentially remove `email` from the `req.body` and leave the rest in `update` as a variable. Note that `findOneAndUpdate()` for mongoose wraps the content with `$set` unless you tell it otherwise specifically, so it's generally okay to just remove the field from any input. Setting up "field level permissions does not really exist for MongoDB or really for mongoose. – Neil Lunn Nov 06 '18 at 07:13

2 Answers2

19

There is a property you can define at the schema level called immutable.

Reference to documentation: https://mongoosejs.com/docs/api/schematype.html#schematype_SchemaType-immutable

So your schema would look like this:

const CustomerSchema = new mongoose.Schema({
    name : {
        type : String,
        required : true,
        trim : true
    },
    email : {
        type : String,
        required : true,
        trim : true,
        immutable: true // ADD THIS PROPERTY HERE
    },
    balance : {
        type : Number ,
        default : 0
    }
}
5

There is no functionality to prevent from update

You can do by removing email object from body

delete req.body.email;
const customer =  await Customer.findOneAndUpdate({_id : req.params.id}, req.body);
Community
  • 1
  • 1
IftekharDani
  • 3,619
  • 1
  • 16
  • 21
  • Is passing `req.body` safe? Fore example, this is a Customer update endpoint maybe. What if it's hit with an API call with a password field set? – doc-han Sep 05 '21 at 06:36