Mongoose how to prevent user already with username to change username

I have an auth system where the user can signup

c username

/ password

or facebook signin

c provider

/providerId

I want to prevent the username from being changed, but if they use facebook

, I allow them to install username

once. Is it possible to implement it in the model user

?

Here is my current implementation.

//username check unique
UserSchema.pre('save', true, function(next, done) {
    var self = this //in case inside a callback



    //sns provider, OK not to have username
    if (self.provider && self.provider !== 'local' && !self.username) {
        done()
        return next()
    }
    //not modified
    if (! self.isModified('username')) {
        done()
        return next()
    }

    mongoose.model('User').findOne({username: self.username}, function(err, user) {
        if (err) {
            done(err)
        } else if (user) {
            //todo: put msg in validation.js
            self.invalidate('username', 'username must be unique')
            done(helper.getValidationError('username must be unique'))
        } else {
            done()
        }
    })

    return next()
})

//username check is valid username
UserSchema.pre('save', true, function(next, done) {
    var self = this

    if (self.provider && self.provider !== 'local' && !self.username) {
        done()
        return next()
    }
    //username is required for local strategy
    var msg = helper.validation.user.username(self.username)
    if (msg) {
        self.invalidate('username', msg)
        done(helper.getValidationError(msg))
    }
    else {
        done()
    }

    return next()
})

      

Assistant confirmation is defined as:

exports.user = {
    username: function(input) {
        if (!input)
            return 'username is required' //Note: required only for Local Strategy
        var min = 3
        var max = 10
        if (input.length < min)
            return 'username min of length is ' + min
        if (input.length > max)
            return 'username max of length is ' + max
        return null
    }
}

      

+3


source to share


2 answers


You can check if the original username is empty. All checks are given in the model. You don't need to change anything in the controller or router.



UserSchema.post('init', function() {
    this.original = this.toObject()
})





UserSchema.pre('save', true, function(next, done) {
    var self = this

    if (! self.isModified('username')) {
        done()
        return next()
    }

    //To prevent Facebook user to delete username (and recreate a different one) with !self.original.username
    if (self.provider && self.provider !== 'local' && !self.username && !self.original.username) {
        done()
        return next()
    }

    //prevent change of username
    if (self.original.username) {
        self.invalidate('username', 'cannot modify username')
        done(helper.getValidationError('cannot modify username'))
    }

    mongoose.model('User').findOne({username: self.username}, function(err, user) {
        if (err) {
            done(err)
        } else if (user) {
            self.invalidate('username', 'username must be unique')
            done(helper.getValidationError('username must be unique'))
        } else {
            done()
        }
    })

    return next()
})

      

+3


source


Try setting your username to null in the prestore function. This should prevent the user from updating his username.

There is also the option to remove the username from the request body:



delete req.body.username;
User.update(query, req.body , options, callback)

      

0


source







All Articles