Q:

Is my approach wrong? I'm confused with NodeJS, MongoDB, Joi, Bcrypt

I have some problems with NodeJS(ExpressJS), MongoDB, Joi Validation Module and Bcrypt.
I have User API router and User Model.
My User Model is This:
const userSchema = new mongoose.Schema({
    name: {
        type: String,
        trim: true,
        minlength: [3, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        validate: {
            validator: function(v) {
                return /^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/.test(v);
            },
            message: 'Uygun Formatta İsim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)'
        },
        match: [/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/, 'Uygun Formatta İsim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)']
    },
    lastname: {
        type: String,
        trim: true,
        minlength: [3, 'Soyadınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        validate: {
            validator: function(v) {
                return /^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/.test(v);
            },
            message: 'Uygun Formatta Soyisim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)'
        },
        match: [/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/, 'Uygun Formatta Soyisim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)']
    },
    username: {
        type: String,
        trim: true,
        index: true,
        unique: true,
        minlength: [3, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
        maxlength: [20, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
        validate: {
            validator: function(v) {
                let re = /^\w+$/;
                return re.test(v);
            },
            message: 'Uygun Formatta Kullanıcı Adı Giriniz. (Geçerli Karakterler: a-z, A-Z, _.)'
        },
        match: [/^\w+$/, 'Uygun Formatta Kullanıcı Adı Giriniz. (Geçerli Karakterler: a-z, A-Z, _.)']
    },
    email: {
        type: String,
        trim: true,
        index: true,
        unique: true,
        validate: {
            validator: function(v) {
                let re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
                return re.test(v);
            },
        message: 'Uygun Formatta E-Posta Adresi Giriniz.'
        },
        match: [/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 'Uygun Formatta E-Posta Adresi Giriniz.']
    },
    password: {
        type: String,
        trim: true,
        required: [true, 'Şifrenizi Girmeniz Gerekmektedir.'],
        minlength: 5,
        maxlength: 1024
    },
    elo: {
        type: Number,
        min: 0,
        required: false,
        default: 0
    },
    rank: {
        type: Number,
        min: -1,
        required: false,
        default: 0
    },
    registerDate: {
        type: Date,
        default: Date.now
    },
    isAdmin: {
        type: Boolean,
        required: true,
        default: false
    }
});

And this is Joi Validation Schema:
const Schema = {
    name: Joi.string().min(3).max(50).regex(/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/),
    lastname: Joi.string().min(3).max(50).regex(/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/),
    username: Joi.string().required().min(3).max(25).regex(/^\w+$/),
    email: Joi.string().required().min(3).email(),
    password: Joi.string().required().min(5).max(255),
    elo: Joi.number().default(0).min(0),
    rank: Joi.number().default(0).min(-1),
    isAdmin: Joi.boolean().default(false)
};

This is sample User:
_id:5b47aae43cf7710e7047c033
elo:0
rank:0
isAdmin:true
name:"Furkan"
lastname:"Taştan"
username:"praaven"
email:"furkantastan@superonline.com"
password:"$2b$10$4xKTxmQnV5mnGrCccpQsY.A8j5ACCdmCHIihDdW0NXmcOcRCcwwPq"
registerDate:2018-07-12 22:24:20.778
__v:0

I'm confusing on Update API Router.
router.put('/:id', auth, async (req, res) => {
    try {
        const errorId = validateUserId(req.params.id);
        if(errorId.error) return res.status(400).send({'Hata': errorId.error.details[0].message});
        const { error } = validateUser(req.body);
        if(error) return res.status(400).send({'Hata': error.details[0].message});
        const salt = await bcyript.genSalt(10);
        const user = await User.findByIdAndUpdate(req.params.id, {
            name: req.body.name,
            lastname: req.body.lastname,
            username: req.body.username,
            email: req.body.email,
            password: await bcyript.hash(req.body.password, salt),
            elo: req.body.elo,
            rank: req.body.rank,
            isAdmin: req.body.isAdmin
        }, { new: true, runValidators: true, context: 'query' });
        if(!user) return res.status(404).send({'Hata': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
        res.status(200).send(_.pick(user, ['_id', 'name', 'lastname', 'username', 'email', 'elo', 'rank', 'registerDate', 'isAdmin']));
    } catch(e) {
        res.status(400).send({ 'Hata': e.message.replace(/(Validation failed|email|username|phone|team)/gi, v => arrayMap[v]) });
    }
});

The problem is, why I need every Update User's password? I don't want User's password, i want to use it on optional. I think, my Update Router is wrong, I'm new on NodeJS RESTful API Coding, can you help me with the true of it's?
Thanks, have a good day!

A:

You are already validating the password field at the Schema level in here:
password: {
        type: String,
        trim: true,
        required: [true, 'Şifrenizi Girmeniz Gerekmektedir.'],
        minlength: 5,
        maxlength: 1024
    },

so no need to re-validate it with required() inside JOI schema.
Since you are using Mongoose, you could use pre functions inside your userSchema. Like this:
/**
 * Hash password with blowfish algorithm (bcrypt) before saving it in to the database
 */
userSchema.pre('save', function(next) {
    var user = this;

    // only hash the password if it has been modified
    if (!user.isModified('password'))
        return next();

    // password will be hashed only if it has changed
    user.password = bcrypt.hash(user.password, bcrypt.genSalt(10));
    next();
});

