vue-express-mongo-boilerplate
Version:
Express NodeJS application server boilerplate with Mongo and VueJS
254 lines (220 loc) • 5.02 kB
JavaScript
;
let config = require("../config");
let logger = require("../core/logger");
let C = require("../core/constants");
let fs = require("fs");
let path = require("path");
let _ = require("lodash");
let crypto = require("crypto");
let bcrypt = require("bcrypt-nodejs");
let db = require("../core/mongo");
let mongoose = require("mongoose");
let Schema = mongoose.Schema;
let hashids = require("../libs/hashids")("users");
let autoIncrement = require("mongoose-auto-increment");
let schemaOptions = {
timestamps: true,
toObject: {
virtuals: true
},
toJSON: {
virtuals: true
}
};
let validateLocalStrategyProperty = function(property) {
return (this.provider !== "local" && !this.updated) || property.length;
};
let validateLocalStrategyPassword = function(password) {
return this.provider !== "local" || (password && password.length >= 6);
};
let UserSchema = new Schema({
fullName: {
type: String,
trim: true,
"default": "",
validate: [validateLocalStrategyProperty, "Please fill in your full name"]
},
email: {
type: String,
trim: true,
unique: true,
index: true,
lowercase: true,
"default": "",
validate: [validateLocalStrategyProperty, "Please fill in your email"],
match: [/.+\@.+\..+/, "Please fill a valid email address"]
},
username: {
type: String,
unique: true,
index: true,
lowercase: true,
required: "Please fill in a username",
trim: true,
match: [/^[\w][\w\-\._\@]*[\w]$/, "Please fill a valid username"]
},
password: {
type: String,
"default": "",
validate: [validateLocalStrategyPassword, "Password should be longer"]
},
passwordLess: {
type: Boolean,
default: false
},
passwordLessToken: {
type: String
},
provider: {
type: String,
"default": "local"
},
profile: {
name: { type: String },
gender: { type: String },
picture: { type: String },
location: { type: String }
},
socialLinks: {
facebook: { type: String, unique: true, sparse: true },
twitter: { type: String, unique: true, sparse: true },
google: { type: String, unique: true, sparse: true },
github: { type: String, unique: true, sparse: true }
},
roles: {
type: [
{
type: String,
"enum": [
C.ROLE_ADMIN,
C.ROLE_USER,
C.ROLE_GUEST
]
}
],
"default": [C.ROLE_USER]
},
resetPasswordToken: String,
resetPasswordExpires: Date,
verified: {
type: Boolean,
default: false
},
verifyToken: {
type: String
},
apiKey: {
type: String,
unique: true,
index: true,
sparse: true
},
lastLogin: {
type: Date
},
locale: {
type: String
},
status: {
type: Number,
default: 1
},
metadata: {}
}, schemaOptions);
/**
* Virtual `code` field instead of _id
*/
UserSchema.virtual("code").get(function() {
return this.encodeID();
});
/**
* Auto increment for `_id`
*/
UserSchema.plugin(autoIncrement.plugin, {
model: "User",
startAt: 1
});
/**
* Password hashing
*/
UserSchema.pre("save", function(next) {
let user = this;
if (!user.isModified("password"))
return next();
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(user.password, salt, null, function(err, hash) {
user.password = hash;
next();
});
});
});
/**
* Password compare
*/
UserSchema.methods.comparePassword = function(password, cb) {
bcrypt.compare(password, this.password, function(err, isMatch) {
cb(err, isMatch);
});
};
/**
* Virtual field for `avatar`.
*/
UserSchema.virtual("avatar").get(function() {
// Load picture from profile
if (this.profile && this.profile.picture)
return this.profile.picture;
// Generate a gravatar picture
if (!this.email)
return "https://gravatar.com/avatar/?s=64&d=wavatar";
let md5 = crypto.createHash("md5").update(this.email).digest("hex");
return "https://gravatar.com/avatar/" + md5 + "?s=64&d=wavatar";
});
/**
* Encode `_id` to `code`
*/
UserSchema.methods.encodeID = function() {
return hashids.encodeHex(this._id);
};
/**
* Decode `code` to `_id`
*/
UserSchema.methods.decodeID = function(code) {
return hashids.decodeHex(code);
};
/**
* Pick is only some fields of object
*
* http://mongoosejs.com/docs/api.html#document_Document-toObject
*
UserSchema.methods.pick = function(props, model) {
return _.pick(model || this.toJSON(), props || [
"code",
"fullName",
"email",
"username",
"roles",
"lastLogin",
"avatar"
]);
};
UserSchema.method('toJSON', function() {
var user = this.toObject();
delete user.salt;
delete user.hash;
delete user.__v;
return user;
});
*/
/*
UserSchema.methods.gravatar = function (size, defaults) {
if (!size)
size = 200;
if (!defaults)
defaults = 'wavatar';
if (!this.email)
return `https://gravatar.com/avatar/?s=${size}&d=${defaults}`;
let md5 = crypto.createHash('md5').update(this.email).digest("hex");
return `https://gravatar.com/avatar/${md5}?s=${size}&d=${defaults}`;
};*/
let User = mongoose.model("User", UserSchema);
module.exports = User;