node-express-mongodb-jwt-rest-api-skeleton
Version:
Node.js express.js MongoDB JWT REST API - This is a basic API REST skeleton written on JavaScript using async/await. Great for building a starter web API for your front-end (Android, iOS, Vue, react, angular, or anything that can consume an API)
120 lines (114 loc) • 2.39 kB
JavaScript
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const validator = require('validator')
const mongoosePaginate = require('mongoose-paginate-v2')
const UserSchema = new mongoose.Schema(
{
name: {
type: String,
required: true
},
email: {
type: String,
validate: {
validator: validator.isEmail,
message: 'EMAIL_IS_NOT_VALID'
},
lowercase: true,
unique: true,
required: true
},
password: {
type: String,
required: true,
select: false
},
role: {
type: String,
enum: ['user', 'admin'],
default: 'user'
},
verification: {
type: String
},
verified: {
type: Boolean,
default: false
},
phone: {
type: String
},
city: {
type: String
},
country: {
type: String
},
urlTwitter: {
type: String,
validate: {
validator(v) {
return v === '' ? true : validator.isURL(v)
},
message: 'NOT_A_VALID_URL'
},
lowercase: true
},
urlGitHub: {
type: String,
validate: {
validator(v) {
return v === '' ? true : validator.isURL(v)
},
message: 'NOT_A_VALID_URL'
},
lowercase: true
},
loginAttempts: {
type: Number,
default: 0,
select: false
},
blockExpires: {
type: Date,
default: Date.now,
select: false
}
},
{
versionKey: false,
timestamps: true
}
)
const hash = (user, salt, next) => {
bcrypt.hash(user.password, salt, (error, newHash) => {
if (error) {
return next(error)
}
user.password = newHash
return next()
})
}
const genSalt = (user, SALT_FACTOR, next) => {
bcrypt.genSalt(SALT_FACTOR, (err, salt) => {
if (err) {
return next(err)
}
return hash(user, salt, next)
})
}
UserSchema.pre('save', function (next) {
const that = this
const SALT_FACTOR = 5
if (!that.isModified('password')) {
return next()
}
return genSalt(that, SALT_FACTOR, next)
})
UserSchema.methods.comparePassword = function (passwordAttempt, cb) {
bcrypt.compare(passwordAttempt, this.password, (err, isMatch) =>
err ? cb(err) : cb(null, isMatch)
)
}
UserSchema.plugin(mongoosePaginate)
module.exports = mongoose.model('User', UserSchema)