Last active
January 24, 2024 06:50
-
-
Save jzellis/41038ac461433b32174a8c556f5aff76 to your computer and use it in GitHub Desktop.
Boilerplate for simple Mongoose user schema
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I find myself recreating user models for Mongoose every time I start a new project, so I thought I'd create a generic schema for a user model that can be added to or modified as need be. | |
This is loosely based on the Meteor user model (using a "profile" sub-object for the user's personal information). It also includes an optional geolocation point for the user, and Mongoose timestamps, as well as a pre("save") function to bcrypt the user password and a comparePassword() function. | |
Just save this file wherever you store your models and do something like const Users = include('./models/userSchema.js') and you can just use it as a standard Mongoose user model. | |
The username/email address definitions were copied from this tutorial: https://thinkster.io/tutorials/node-json-api/creating-the-user-model | |
*/ | |
const mongoose = require('mongoose'), | |
Schema = mongoose.Schema, | |
uniqueValidator = require('mongoose-unique-validator'), | |
bcrypt = require('bcrypt'), | |
SALT_WORK_FACTOR = 10; | |
const Email = new Schema({ | |
address: {type: String, lowercase: true, required: [true, "can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true}, | |
// Change the default to true if you don't need to validate a new user's email address | |
validated: {type: Boolean, default: false} | |
}); | |
const Point = new mongoose.Schema({ | |
type: { | |
type: String, | |
enum: ['Point'], | |
required: true | |
}, | |
coordinates: { | |
type: [Number], | |
required: true | |
} | |
}); | |
const UserSchema = new Schema({ | |
username: {type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true}, | |
//Our password is hashed with bcrypt | |
password: { type: String, required: true }, | |
email: {type: Email, required: true}, | |
profile: { | |
firstName: String, | |
lastName: String, | |
avatar: String, | |
bio: String, | |
address: { | |
street1: String, | |
street2: String, | |
city: String, | |
state: String, | |
country: String, | |
zip: String, | |
location: { | |
type: Point, | |
required: false | |
} | |
} | |
}, | |
active: {type: Boolean, default: true} | |
},{ | |
timestamps:true | |
}); | |
UserSchema.plugin(uniqueValidator, {message: 'is already taken.'}); | |
UserSchema.pre("save", function(next) { | |
if(!this.isModified("password")) { | |
return next(); | |
} | |
this.password = bcrypt.hashSync(this.password, 10); | |
next(); | |
}); | |
UserSchema.methods.comparePassword = function(plaintext, callback) { | |
return callback(null, bcrypt.compareSync(plaintext, this.password)); | |
}; | |
module.exports = mongoose.model("User", UserSchema); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment