UNPKG

create-bodhi-node-boilerplate

Version:

Create a Node.js project with basic folder structure and server setup

105 lines (95 loc) 2.79 kB
const mongoose = require('mongoose'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const config = require('../config/config'); const userSchema = new mongoose.Schema({ username: { type: String, required: [true, 'Please provide a username'], unique: true, trim: true, minlength: [3, 'Username must be at least 3 characters long'], maxlength: [30, 'Username cannot be more than 30 characters'], lowercase: true, match: [ /^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores' ] }, email: { type: String, required: [true, 'Please provide an email'], unique: true, lowercase: true, trim: true, match: [ /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/, 'Please provide a valid email' ] }, password: { type: String, required: [true, 'Please provide a password'], minlength: [6, 'Password must be at least 6 characters long'], select: false }, refreshTokenHash: { type: String, select: false }, createdAt: { type: Date, default: Date.now }, lastLogin: { type: Date } }, { timestamps: true }); // Hash password before saving userSchema.pre('save', async function(next) { if (!this.isModified('password')) { next(); } const salt = await bcrypt.genSalt(10); this.password = await bcrypt.hash(this.password, salt); }); // Sign JWT access token userSchema.methods.getSignedJwtToken = function() { return jwt.sign( { id: this._id }, config.jwt.secret, { expiresIn: config.jwt.accessExpire } ); }; // Sign refresh token userSchema.methods.getRefreshToken = function() { return jwt.sign( { id: this._id }, config.jwt.refreshSecret, { expiresIn: config.jwt.refreshExpire } ); }; // Match password userSchema.methods.matchPassword = async function(enteredPassword) { return await bcrypt.compare(enteredPassword, this.password); }; // Hash refresh token for storage userSchema.methods.hashToken = async function(token) { const salt = await bcrypt.genSalt(10); return await bcrypt.hash(token, salt); }; // Verify refresh token userSchema.methods.verifyRefreshToken = async function(token) { if (!this.refreshTokenHash) return false; return await bcrypt.compare(token, this.refreshTokenHash); }; // Remove sensitive fields when converting to JSON userSchema.methods.toJSON = function() { const obj = this.toObject(); delete obj.password; delete obj.refreshTokenHash; return obj; }; module.exports = mongoose.model('User', userSchema);