Puesto que vamos a guardar los detalles de usuario en Mongo, vamos a crear un modelo de usuario en Mongoose vamos a guardar este modelo dentro de la carpeta /api/user puesto que también estos registros serán expuestos atraves de una API.
Primero vamos a instalar las dependencias que vamos a necesitar para esta parte.
Los esquemas virtuales son campos adicionales para un modelo dado. Sus valores se pueden configurar de forma manual o automática con la funcionalidad definida. Una propiedad virtual común es el nombre completo de una persona, compuesto por el nombre y apellido del usuario.
Vamos agregar a nuestro archivo api/user/user.model.js el siguiente código:
api/user/user.model.js
/** * Virtuals */// Public profile informationUserSchema.virtual('profile').get(function () {return { name:this.name, role:this.role, }; });// Non-sensitive info we'll be putting in the tokenUserSchema.virtual('token').get(function () {return { _id:this._id, role:this.role, }; });
Schema Validation
La validación de esquema de JSON extiende la validación de documentos de muchas maneras diferentes, incluida la capacidad de imponer esquemas dentro de arrays y evitar que se agreguen atributos no aprobados.
Para nuestro caso de uso vamos adicionar validaciones para el campo email y password con el siguiente código:
api/user/user.model.js
/** * Validations */// Validate empty emailUserSchema.path('email').validate(function (email) {if (authTypes.indexOf(this.provider) !==-1) {returntrue; }returnemail.length; },'Email cannot be blank');// Validate empty passwordUserSchema.path('password').validate(function (password) {if (authTypes.indexOf(this.provider) !==-1) {returntrue; }returnpassword.length; },'Password cannot be blank');// Validate email is not takenUserSchema.path('email').validate(function (value) {if (authTypes.indexOf(this.provider) !==-1) {returntrue; }returnthis.constructor.findOne({ email: value }).exec().then((user) => {if (user) {if (this.id ===user.id) {returntrue; }returnfalse; }returntrue; }).catch((err) => {throw err; }); },'The specified email address is already in use.');
Schema Hook
api/user/user.model.js
constvalidatePresenceOf=function (value) {return value &&value.length;};/** * Pre-save hook */UserSchema.pre('save',function (next) {// Handle new/update passwordsif (!this.isModified('password')) {returnnext(); }if (!validatePresenceOf(this.password)) {if (authTypes.indexOf(this.provider) ===-1) {returnnext(newError('Invalid password')); }returnnext(); }// Make salt with a callbackreturnthis.makeSalt((saltErr, salt) => {if (saltErr) {returnnext(saltErr); }this.salt = salt;this.encryptPassword(this.password, (encryptErr, hashedPassword) => {if (encryptErr) {returnnext(encryptErr); }this.password = hashedPassword;returnnext(); }); }); });