From 4209233824bab7462a36b1a6524234f906c1bf20 Mon Sep 17 00:00:00 2001 From: kburd Date: Mon, 15 Mar 2021 16:43:54 -0400 Subject: [PATCH] cleaning up --- controllers/auth.js | 49 +---------------------------------- controllers/bootcamps.js | 34 ------------------------ controllers/courses.js | 19 -------------- controllers/reviews.js | 18 ------------- controllers/users.js | 15 ----------- middleware/advancedResults.js | 11 -------- middleware/auth.js | 9 ------- middleware/error.js | 4 --- middleware/logger.js | 2 +- models/Bootcamp.js | 7 ----- models/Course.js | 3 --- models/Review.js | 4 --- models/User.js | 9 ------- routes/bootcamps.js | 2 -- seeder.js | 6 ----- server.js | 20 +------------- 16 files changed, 3 insertions(+), 209 deletions(-) diff --git a/controllers/auth.js b/controllers/auth.js index ea8f729..ab16b89 100644 --- a/controllers/auth.js +++ b/controllers/auth.js @@ -4,13 +4,9 @@ const asyncHandler = require('../middleware/async'); const sendEmail = require('../utils/sendEmail'); const User = require('../models/User'); -// @desc Register user -// @route POST /api/v1/auth/register -// @access Public exports.register = asyncHandler(async (req, res, next) => { const { name, email, password, role } = req.body; - // Create user const user = await User.create({ name, email, @@ -18,10 +14,8 @@ exports.register = asyncHandler(async (req, res, next) => { role, }); - // grab token and send to email const confirmEmailToken = user.generateEmailConfirmToken(); - // Create reset url const confirmEmailURL = `${req.protocol}://${req.get( 'host', )}/api/v1/auth/confirmemail?token=${confirmEmailToken}`; @@ -39,25 +33,20 @@ exports.register = asyncHandler(async (req, res, next) => { sendTokenResponse(user, 200, res); }); -// @desc Login user -// @route POST /api/v1/auth/login -// @access Public + exports.login = asyncHandler(async (req, res, next) => { const { email, password } = req.body; - // Validate emil & password if (!email || !password) { return next(new ErrorResponse('Please provide an email and password', 400)); } - // Check for user const user = await User.findOne({ email }).select('+password'); if (!user) { return next(new ErrorResponse('Invalid credentials', 401)); } - // Check if password matches const isMatch = await user.matchPassword(password); if (!isMatch) { @@ -67,9 +56,6 @@ exports.login = asyncHandler(async (req, res, next) => { sendTokenResponse(user, 200, res); }); -// @desc Log user out / clear cookie -// @route GET /api/v1/auth/logout -// @access Public exports.logout = asyncHandler(async (req, res, next) => { res.cookie('token', 'none', { expires: new Date(Date.now() + 10 * 1000), @@ -82,11 +68,7 @@ exports.logout = asyncHandler(async (req, res, next) => { }); }); -// @desc Get current logged in user -// @route GET /api/v1/auth/me -// @access Private exports.getMe = asyncHandler(async (req, res, next) => { - // user is already available in req due to the protect middleware const user = req.user; res.status(200).json({ @@ -95,9 +77,6 @@ exports.getMe = asyncHandler(async (req, res, next) => { }); }); -// @desc Update user details -// @route PUT /api/v1/auth/updatedetails -// @access Private exports.updateDetails = asyncHandler(async (req, res, next) => { const fieldsToUpdate = { name: req.body.name, @@ -115,13 +94,9 @@ exports.updateDetails = asyncHandler(async (req, res, next) => { }); }); -// @desc Update password -// @route PUT /api/v1/auth/updatepassword -// @access Private exports.updatePassword = asyncHandler(async (req, res, next) => { const user = await User.findById(req.user.id).select('+password'); - // Check current password if (!(await user.matchPassword(req.body.currentPassword))) { return next(new ErrorResponse('Password is incorrect', 401)); } @@ -132,9 +107,6 @@ exports.updatePassword = asyncHandler(async (req, res, next) => { sendTokenResponse(user, 200, res); }); -// @desc Forgot password -// @route POST /api/v1/auth/forgotpassword -// @access Public exports.forgotPassword = asyncHandler(async (req, res, next) => { const user = await User.findOne({ email: req.body.email }); @@ -142,12 +114,10 @@ exports.forgotPassword = asyncHandler(async (req, res, next) => { return next(new ErrorResponse('There is no user with that email', 404)); } - // Get reset token const resetToken = user.getResetPasswordToken(); await user.save({ validateBeforeSave: false }); - // Create reset url const resetUrl = `${req.protocol}://${req.get( 'host', )}/api/v1/auth/resetpassword/${resetToken}`; @@ -173,11 +143,7 @@ exports.forgotPassword = asyncHandler(async (req, res, next) => { } }); -// @desc Reset password -// @route PUT /api/v1/auth/resetpassword/:resettoken -// @access Public exports.resetPassword = asyncHandler(async (req, res, next) => { - // Get hashed token const resetPasswordToken = crypto .createHash('sha256') .update(req.params.resettoken) @@ -192,7 +158,6 @@ exports.resetPassword = asyncHandler(async (req, res, next) => { return next(new ErrorResponse('Invalid token', 400)); } - // Set new password user.password = req.body.password; user.resetPasswordToken = undefined; user.resetPasswordExpire = undefined; @@ -201,13 +166,7 @@ exports.resetPassword = asyncHandler(async (req, res, next) => { sendTokenResponse(user, 200, res); }); -/** - * @desc Confirm Email - * @route GET /api/v1/auth/confirmemail - * @access Public - */ exports.confirmEmail = asyncHandler(async (req, res, next) => { - // grab token from email const { token } = req.query; if (!token) { @@ -220,7 +179,6 @@ exports.confirmEmail = asyncHandler(async (req, res, next) => { .update(splitToken) .digest('hex'); - // get user by token const user = await User.findOne({ confirmEmailToken, isEmailConfirmed: false, @@ -230,20 +188,15 @@ exports.confirmEmail = asyncHandler(async (req, res, next) => { return next(new ErrorResponse('Invalid Token', 400)); } - // update confirmed to true user.confirmEmailToken = undefined; user.isEmailConfirmed = true; - // save user.save({ validateBeforeSave: false }); - // return token sendTokenResponse(user, 200, res); }); -// Get token from model, create cookie and send response const sendTokenResponse = (user, statusCode, res) => { - // Create token const token = user.getSignedJwtToken(); const options = { diff --git a/controllers/bootcamps.js b/controllers/bootcamps.js index 90a8fe7..d00030f 100644 --- a/controllers/bootcamps.js +++ b/controllers/bootcamps.js @@ -4,16 +4,10 @@ const asyncHandler = require('../middleware/async'); const geocoder = require('../utils/geocoder'); const Bootcamp = require('../models/Bootcamp'); -// @desc Get all bootcamps -// @route GET /api/v1/bootcamps -// @access Public exports.getBootcamps = asyncHandler(async (req, res, next) => { res.status(200).json(res.advancedResults); }); -// @desc Get single bootcamp -// @route GET /api/v1/bootcamps/:id -// @access Public exports.getBootcamp = asyncHandler(async (req, res, next) => { const bootcamp = await Bootcamp.findById(req.params.id); @@ -26,17 +20,11 @@ exports.getBootcamp = asyncHandler(async (req, res, next) => { res.status(200).json({ success: true, data: bootcamp }); }); -// @desc Create new bootcamp -// @route POST /api/v1/bootcamps -// @access Private exports.createBootcamp = asyncHandler(async (req, res, next) => { - // Add user to req,body req.body.user = req.user.id; - // Check for published bootcamp const publishedBootcamp = await Bootcamp.findOne({ user: req.user.id }); - // If the user is not an admin, they can only add one bootcamp if (publishedBootcamp && req.user.role !== 'admin') { return next( new ErrorResponse( @@ -54,9 +42,6 @@ exports.createBootcamp = asyncHandler(async (req, res, next) => { }); }); -// @desc Update bootcamp -// @route PUT /api/v1/bootcamps/:id -// @access Private exports.updateBootcamp = asyncHandler(async (req, res, next) => { let bootcamp = await Bootcamp.findById(req.params.id); @@ -66,7 +51,6 @@ exports.updateBootcamp = asyncHandler(async (req, res, next) => { ); } - // Make sure user is bootcamp owner if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') { return next( new ErrorResponse( @@ -84,9 +68,6 @@ exports.updateBootcamp = asyncHandler(async (req, res, next) => { res.status(200).json({ success: true, data: bootcamp }); }); -// @desc Delete bootcamp -// @route DELETE /api/v1/bootcamps/:id -// @access Private exports.deleteBootcamp = asyncHandler(async (req, res, next) => { const bootcamp = await Bootcamp.findById(req.params.id); @@ -96,7 +77,6 @@ exports.deleteBootcamp = asyncHandler(async (req, res, next) => { ); } - // Make sure user is bootcamp owner if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') { return next( new ErrorResponse( @@ -111,20 +91,13 @@ exports.deleteBootcamp = asyncHandler(async (req, res, next) => { res.status(200).json({ success: true, data: {} }); }); -// @desc Get bootcamps within a radius -// @route GET /api/v1/bootcamps/radius/:zipcode/:distance -// @access Private exports.getBootcampsInRadius = asyncHandler(async (req, res, next) => { const { zipcode, distance } = req.params; - // Get lat/lng from geocoder const loc = await geocoder.geocode(zipcode); const lat = loc[0].latitude; const lng = loc[0].longitude; - // Calc radius using radians - // Divide dist by radius of Earth - // Earth Radius = 3,963 mi / 6,378 km const radius = distance / 3963; const bootcamps = await Bootcamp.find({ @@ -138,9 +111,6 @@ exports.getBootcampsInRadius = asyncHandler(async (req, res, next) => { }); }); -// @desc Upload photo for bootcamp -// @route PUT /api/v1/bootcamps/:id/photo -// @access Private exports.bootcampPhotoUpload = asyncHandler(async (req, res, next) => { const bootcamp = await Bootcamp.findById(req.params.id); @@ -150,7 +120,6 @@ exports.bootcampPhotoUpload = asyncHandler(async (req, res, next) => { ); } - // Make sure user is bootcamp owner if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') { return next( new ErrorResponse( @@ -166,12 +135,10 @@ exports.bootcampPhotoUpload = asyncHandler(async (req, res, next) => { const file = req.files.file; - // Make sure the image is a photo if (!file.mimetype.startsWith('image')) { return next(new ErrorResponse(`Please upload an image file`, 400)); } - // Check filesize if (file.size > process.env.MAX_FILE_UPLOAD) { return next( new ErrorResponse( @@ -181,7 +148,6 @@ exports.bootcampPhotoUpload = asyncHandler(async (req, res, next) => { ); } - // Create custom filename file.name = `photo_${bootcamp._id}${path.parse(file.name).ext}`; file.mv(`${process.env.FILE_UPLOAD_PATH}/${file.name}`, async err => { diff --git a/controllers/courses.js b/controllers/courses.js index c96b0e6..40a4521 100644 --- a/controllers/courses.js +++ b/controllers/courses.js @@ -3,10 +3,6 @@ const asyncHandler = require('../middleware/async'); const Course = require('../models/Course'); const Bootcamp = require('../models/Bootcamp'); -// @desc Get courses -// @route GET /api/v1/courses -// @route GET /api/v1/bootcamps/:bootcampId/courses -// @access Public exports.getCourses = asyncHandler(async (req, res, next) => { if (req.params.bootcampId) { const courses = await Course.find({ bootcamp: req.params.bootcampId }); @@ -21,9 +17,6 @@ exports.getCourses = asyncHandler(async (req, res, next) => { } }); -// @desc Get single course -// @route GET /api/v1/courses/:id -// @access Public exports.getCourse = asyncHandler(async (req, res, next) => { const course = await Course.findById(req.params.id).populate({ path: 'bootcamp', @@ -42,9 +35,6 @@ exports.getCourse = asyncHandler(async (req, res, next) => { }); }); -// @desc Add course -// @route POST /api/v1/bootcamps/:bootcampId/courses -// @access Private exports.addCourse = asyncHandler(async (req, res, next) => { req.body.bootcamp = req.params.bootcampId; req.body.user = req.user.id; @@ -60,7 +50,6 @@ exports.addCourse = asyncHandler(async (req, res, next) => { ); } - // Make sure user is bootcamp owner if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') { return next( new ErrorResponse( @@ -78,9 +67,6 @@ exports.addCourse = asyncHandler(async (req, res, next) => { }); }); -// @desc Update course -// @route PUT /api/v1/courses/:id -// @access Private exports.updateCourse = asyncHandler(async (req, res, next) => { let course = await Course.findById(req.params.id); @@ -90,7 +76,6 @@ exports.updateCourse = asyncHandler(async (req, res, next) => { ); } - // Make sure user is course owner if (course.user.toString() !== req.user.id && req.user.role !== 'admin') { return next( new ErrorResponse( @@ -113,9 +98,6 @@ exports.updateCourse = asyncHandler(async (req, res, next) => { }); }); -// @desc Delete course -// @route DELETE /api/v1/courses/:id -// @access Private exports.deleteCourse = asyncHandler(async (req, res, next) => { const course = await Course.findById(req.params.id); @@ -125,7 +107,6 @@ exports.deleteCourse = asyncHandler(async (req, res, next) => { ); } - // Make sure user is course owner if (course.user.toString() !== req.user.id && req.user.role !== 'admin') { return next( new ErrorResponse( diff --git a/controllers/reviews.js b/controllers/reviews.js index 0e0d3df..e60f38d 100644 --- a/controllers/reviews.js +++ b/controllers/reviews.js @@ -3,10 +3,6 @@ const asyncHandler = require('../middleware/async'); const Review = require('../models/Review'); const Bootcamp = require('../models/Bootcamp'); -// @desc Get reviews -// @route GET /api/v1/reviews -// @route GET /api/v1/bootcamps/:bootcampId/reviews -// @access Public exports.getReviews = asyncHandler(async (req, res, next) => { if (req.params.bootcampId) { const reviews = await Review.find({ bootcamp: req.params.bootcampId }); @@ -21,9 +17,6 @@ exports.getReviews = asyncHandler(async (req, res, next) => { } }); -// @desc Get single review -// @route GET /api/v1/reviews/:id -// @access Public exports.getReview = asyncHandler(async (req, res, next) => { const review = await Review.findById(req.params.id).populate({ path: 'bootcamp', @@ -42,9 +35,6 @@ exports.getReview = asyncHandler(async (req, res, next) => { }); }); -// @desc Add review -// @route POST /api/v1/bootcamps/:bootcampId/reviews -// @access Private exports.addReview = asyncHandler(async (req, res, next) => { req.body.bootcamp = req.params.bootcampId; req.body.user = req.user.id; @@ -68,9 +58,6 @@ exports.addReview = asyncHandler(async (req, res, next) => { }); }); -// @desc Update review -// @route PUT /api/v1/reviews/:id -// @access Private exports.updateReview = asyncHandler(async (req, res, next) => { let review = await Review.findById(req.params.id); @@ -80,7 +67,6 @@ exports.updateReview = asyncHandler(async (req, res, next) => { ); } - // Make sure review belongs to user or user is admin if (review.user.toString() !== req.user.id && req.user.role !== 'admin') { return next(new ErrorResponse(`Not authorized to update review`, 401)); } @@ -98,9 +84,6 @@ exports.updateReview = asyncHandler(async (req, res, next) => { }); }); -// @desc Delete review -// @route DELETE /api/v1/reviews/:id -// @access Private exports.deleteReview = asyncHandler(async (req, res, next) => { const review = await Review.findById(req.params.id); @@ -110,7 +93,6 @@ exports.deleteReview = asyncHandler(async (req, res, next) => { ); } - // Make sure review belongs to user or user is admin if (review.user.toString() !== req.user.id && req.user.role !== 'admin') { return next(new ErrorResponse(`Not authorized to update review`, 401)); } diff --git a/controllers/users.js b/controllers/users.js index ed9a16d..6dde79f 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -2,16 +2,10 @@ const ErrorResponse = require('../utils/errorResponse'); const asyncHandler = require('../middleware/async'); const User = require('../models/User'); -// @desc Get all users -// @route GET /api/v1/users -// @access Private/Admin exports.getUsers = asyncHandler(async (req, res, next) => { res.status(200).json(res.advancedResults); }); -// @desc Get single user -// @route GET /api/v1/users/:id -// @access Private/Admin exports.getUser = asyncHandler(async (req, res, next) => { const user = await User.findById(req.params.id); @@ -21,9 +15,6 @@ exports.getUser = asyncHandler(async (req, res, next) => { }); }); -// @desc Create user -// @route POST /api/v1/users -// @access Private/Admin exports.createUser = asyncHandler(async (req, res, next) => { const user = await User.create(req.body); @@ -33,9 +24,6 @@ exports.createUser = asyncHandler(async (req, res, next) => { }); }); -// @desc Update user -// @route PUT /api/v1/users/:id -// @access Private/Admin exports.updateUser = asyncHandler(async (req, res, next) => { const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true, @@ -48,9 +36,6 @@ exports.updateUser = asyncHandler(async (req, res, next) => { }); }); -// @desc Delete user -// @route DELETE /api/v1/users/:id -// @access Private/Admin exports.deleteUser = asyncHandler(async (req, res, next) => { await User.findByIdAndDelete(req.params.id); diff --git a/middleware/advancedResults.js b/middleware/advancedResults.js index 10d87f1..6eba94f 100644 --- a/middleware/advancedResults.js +++ b/middleware/advancedResults.js @@ -1,31 +1,23 @@ const advancedResults = (model, populate) => async (req, res, next) => { let query; - // Copy req.query const reqQuery = { ...req.query }; - // Fields to exclude const removeFields = ['select', 'sort', 'page', 'limit']; - // Loop over removeFields and delete them from reqQuery removeFields.forEach(param => delete reqQuery[param]); - // Create query string let queryStr = JSON.stringify(reqQuery); - // Create operators ($gt, $gte, etc) queryStr = queryStr.replace(/\b(gt|gte|lt|lte|in)\b/g, match => `$${match}`); - // Finding resource query = model.find(JSON.parse(queryStr)); - // Select Fields if (req.query.select) { const fields = req.query.select.split(',').join(' '); query = query.select(fields); } - // Sort if (req.query.sort) { const sortBy = req.query.sort.split(',').join(' '); query = query.sort(sortBy); @@ -33,7 +25,6 @@ const advancedResults = (model, populate) => async (req, res, next) => { query = query.sort('-createdAt'); } - // Pagination const page = parseInt(req.query.page, 10) || 1; const limit = parseInt(req.query.limit, 10) || 25; const startIndex = (page - 1) * limit; @@ -46,10 +37,8 @@ const advancedResults = (model, populate) => async (req, res, next) => { query = query.populate(populate); } - // Executing query const results = await query; - // Pagination result const pagination = {}; if (endIndex < total) { diff --git a/middleware/auth.js b/middleware/auth.js index fe5b444..694d1a2 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -3,7 +3,6 @@ const asyncHandler = require('./async'); const ErrorResponse = require('../utils/errorResponse'); const User = require('../models/User'); -// Protect routes exports.protect = asyncHandler(async (req, res, next) => { let token; @@ -11,21 +10,14 @@ exports.protect = asyncHandler(async (req, res, next) => { req.headers.authorization && req.headers.authorization.startsWith('Bearer') ) { - // Set token from Bearer token in header token = req.headers.authorization.split(' ')[1]; - // Set token from cookie } - // else if (req.cookies.token) { - // token = req.cookies.token; - // } - // Make sure token exists if (!token) { return next(new ErrorResponse('Not authorized to access this route', 401)); } try { - // Verify token const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = await User.findById(decoded.id); @@ -36,7 +28,6 @@ exports.protect = asyncHandler(async (req, res, next) => { } }); -// Grant access to specific roles exports.authorize = (...roles) => { return (req, res, next) => { if (!roles.includes(req.user.role)) { diff --git a/middleware/error.js b/middleware/error.js index 30f3e49..30b804b 100644 --- a/middleware/error.js +++ b/middleware/error.js @@ -5,22 +5,18 @@ const errorHandler = (err, req, res, next) => { error.message = err.message; - // Log to console for dev console.log(err); - // Mongoose bad ObjectId if (err.name === 'CastError') { const message = `Resource not found`; error = new ErrorResponse(message, 404); } - // Mongoose duplicate key if (err.code === 11000) { const message = 'Duplicate field value entered'; error = new ErrorResponse(message, 400); } - // Mongoose validation error if (err.name === 'ValidationError') { const message = Object.values(err.errors).map(val => val.message); error = new ErrorResponse(message, 400); diff --git a/middleware/logger.js b/middleware/logger.js index 920a974..905ab4a 100644 --- a/middleware/logger.js +++ b/middleware/logger.js @@ -1,4 +1,4 @@ -// @desc Logs request to console + const logger = (req, res, next) => { console.log( `${req.method} ${req.protocol}://${req.get('host')}${req.originalUrl}` diff --git a/models/Bootcamp.js b/models/Bootcamp.js index 41386b1..53daf44 100644 --- a/models/Bootcamp.js +++ b/models/Bootcamp.js @@ -40,7 +40,6 @@ const BootcampSchema = new mongoose.Schema( required: [true, 'Please add an address'] }, location: { - // GeoJSON Point type: { type: String, enum: ['Point'] @@ -57,7 +56,6 @@ const BootcampSchema = new mongoose.Schema( country: String }, careers: { - // Array of strings type: [String], required: true, enum: [ @@ -111,13 +109,11 @@ const BootcampSchema = new mongoose.Schema( } ); -// Create bootcamp slug from the name BootcampSchema.pre('save', function(next) { this.slug = slugify(this.name, { lower: true }); next(); }); -// Geocode & create location field BootcampSchema.pre('save', async function(next) { const loc = await geocoder.geocode(this.address); this.location = { @@ -131,19 +127,16 @@ BootcampSchema.pre('save', async function(next) { country: loc[0].countryCode }; - // Do not save address in DB this.address = undefined; next(); }); -// Cascade delete courses when a bootcamp is deleted BootcampSchema.pre('remove', async function(next) { console.log(`Courses being removed from bootcamp ${this._id}`); await this.model('Course').deleteMany({ bootcamp: this._id }); next(); }); -// Reverse populate with virtuals BootcampSchema.virtual('courses', { ref: 'Course', localField: '_id', diff --git a/models/Course.js b/models/Course.js index a56a14c..13b3559 100644 --- a/models/Course.js +++ b/models/Course.js @@ -43,7 +43,6 @@ const CourseSchema = new mongoose.Schema({ } }); -// Static method to get avg of course tuitions CourseSchema.statics.getAverageCost = async function(bootcampId) { const obj = await this.aggregate([ { @@ -72,12 +71,10 @@ CourseSchema.statics.getAverageCost = async function(bootcampId) { } }; -// Call getAverageCost after save CourseSchema.post('save', async function() { await this.constructor.getAverageCost(this.bootcamp); }); -// Call getAverageCost after remove CourseSchema.post('remove', async function () { await this.constructor.getAverageCost(this.bootcamp); }); diff --git a/models/Review.js b/models/Review.js index 43b3032..82306b1 100644 --- a/models/Review.js +++ b/models/Review.js @@ -33,10 +33,8 @@ const ReviewSchema = new mongoose.Schema({ } }); -// Prevent user from submitting more than one review per bootcamp ReviewSchema.index({ bootcamp: 1, user: 1 }, { unique: true }); -// Static method to get avg rating and save ReviewSchema.statics.getAverageRating = async function(bootcampId) { const obj = await this.aggregate([ { @@ -59,12 +57,10 @@ ReviewSchema.statics.getAverageRating = async function(bootcampId) { } }; -// Call getAverageCost after save ReviewSchema.post('save', async function() { await this.constructor.getAverageRating(this.bootcamp); }); -// Call getAverageCost before remove ReviewSchema.post('remove', async function() { await this.constructor.getAverageRating(this.bootcamp); }); diff --git a/models/User.js b/models/User.js index 6c80f39..646ec24 100644 --- a/models/User.js +++ b/models/User.js @@ -48,7 +48,6 @@ const UserSchema = new mongoose.Schema({ }, }); -// Encrypt password using bcrypt UserSchema.pre('save', async function (next) { if (!this.isModified('password')) { next(); @@ -58,38 +57,30 @@ UserSchema.pre('save', async function (next) { this.password = await bcrypt.hash(this.password, salt); }); -// Sign JWT and return UserSchema.methods.getSignedJwtToken = function () { return jwt.sign({ id: this._id }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRE, }); }; -// Match user entered password to hashed password in database UserSchema.methods.matchPassword = async function (enteredPassword) { return await bcrypt.compare(enteredPassword, this.password); }; -// Generate and hash password token UserSchema.methods.getResetPasswordToken = function () { - // Generate token const resetToken = crypto.randomBytes(20).toString('hex'); - // Hash token and set to resetPasswordToken field this.resetPasswordToken = crypto .createHash('sha256') .update(resetToken) .digest('hex'); - // Set expire this.resetPasswordExpire = Date.now() + 10 * 60 * 1000; return resetToken; }; -// Generate email confirm token UserSchema.methods.generateEmailConfirmToken = function (next) { - // email confirmation token const confirmationToken = crypto.randomBytes(20).toString('hex'); this.confirmEmailToken = crypto diff --git a/routes/bootcamps.js b/routes/bootcamps.js index 5e9e93f..3322460 100644 --- a/routes/bootcamps.js +++ b/routes/bootcamps.js @@ -11,7 +11,6 @@ const { const Bootcamp = require('../models/Bootcamp'); -// Include other resource routers const courseRouter = require('./courses'); const reviewRouter = require('./reviews'); @@ -20,7 +19,6 @@ const router = express.Router(); const advancedResults = require('../middleware/advancedResults'); const { protect, authorize } = require('../middleware/auth'); -// Re-route into other resource routers router.use('/:bootcampId/courses', courseRouter); router.use('/:bootcampId/reviews', reviewRouter); diff --git a/seeder.js b/seeder.js index 2fa2fe7..f2e5b62 100644 --- a/seeder.js +++ b/seeder.js @@ -3,16 +3,13 @@ const mongoose = require('mongoose'); const colors = require('colors'); const dotenv = require('dotenv'); -// Load env vars dotenv.config({ path: './config/config.env' }); -// Load models const Bootcamp = require('./models/Bootcamp'); const Course = require('./models/Course'); const User = require('./models/User'); const Review = require('./models/Review'); -// Connect to DB mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useCreateIndex: true, @@ -20,7 +17,6 @@ mongoose.connect(process.env.MONGO_URI, { useUnifiedTopology: true }); -// Read JSON files const bootcamps = JSON.parse( fs.readFileSync(`${__dirname}/_data/bootcamps.json`, 'utf-8') ); @@ -37,7 +33,6 @@ const reviews = JSON.parse( fs.readFileSync(`${__dirname}/_data/reviews.json`, 'utf-8') ); -// Import into DB const importData = async () => { try { await Bootcamp.create(bootcamps); @@ -51,7 +46,6 @@ const importData = async () => { } }; -// Delete data const deleteData = async () => { try { await Bootcamp.deleteMany(); diff --git a/server.js b/server.js index e5d6a80..c02a16d 100644 --- a/server.js +++ b/server.js @@ -14,13 +14,10 @@ const cors = require('cors'); const errorHandler = require('./middleware/error'); const connectDB = require('./config/db'); -// Load env vars dotenv.config({ path: './config/config.env' }); -// Connect to database connectDB(); -// Route files const bootcamps = require('./routes/bootcamps'); const courses = require('./routes/courses'); const auth = require('./routes/auth'); @@ -29,46 +26,34 @@ const reviews = require('./routes/reviews'); const app = express(); -// Body parser app.use(express.json()); -// Cookie parser app.use(cookieParser()); -// Dev logging middleware if (process.env.NODE_ENV === 'development') { app.use(morgan('dev')); } -// File uploading app.use(fileupload()); -// Sanitize data app.use(mongoSanitize()); -// Set security headers app.use(helmet()); -// Prevent XSS attacks app.use(xss()); -// Rate limiting const limiter = rateLimit({ - windowMs: 10 * 60 * 1000, // 10 mins + windowMs: 10 * 60 * 1000, max: 100 }); app.use(limiter); -// Prevent http param pollution app.use(hpp()); -// Enable CORS app.use(cors()); -// Set static folder app.use(express.static(path.join(__dirname, 'public'))); -// Mount routers app.use('/api/v1/bootcamps', bootcamps); app.use('/api/v1/courses', courses); app.use('/api/v1/auth', auth); @@ -86,9 +71,6 @@ const server = app.listen( ) ); -// Handle unhandled promise rejections process.on('unhandledRejection', (err, promise) => { console.log(`Error: ${err.message}`.red); - // Close server & exit process - // server.close(() => process.exit(1)); });