- import express and assign to variable
- setup start port variable (5000) and start function
- get connection string
- setup .env with MONGO_URL variable and assign the value
- import 'dotenv' and setup package
- import connect() and invoke in the starter
- restart the server
- mongoose V6 info
- setup / GET Route
- setup express.json() middleware
- setup 404 and errorHandler middleware
- import 'express-async-errors' package
- [] create models folder and User.js file
- [] create schema with name,email, password (all type:String)
- [] export mongoose model
- create controllers folder
- add authController file
- export (register,login,logout) functions
- res.send('some string value')
- create routes folder
- setup authRoutes file
- import all controllers
- setup three routes
- post('/register') post('/login') get('/logout')
- import authRoutes as authRouter in the app.js
- setup app.use('/api/v1/auth', authRouter)
- create user
- send response with entire user (only while testing)
- check if email already in use (schema and controller)
- [] ignore 'role'
- [] alternative 'admin' setup
- [] UserSchema.pre('save') - hook
- this points to User
- bcrypt.genSalt - number of rounds
- bcrypt.hash
- require 'jsonwebtoken' package
- create jwt - jwt.sign(payload,secret,options)
- verify jwt - jwt.verify(token,secret)
- add variables in .env JWT_SECRET=jwtSecret and JWT_LIFETIME=1d
- restart the server !!!!
- refactor code, create jwt functions in utils
- refactor cookie code
- setup func attachCookiesToResponse
- accept payload(res, tokenUser)
- create token, setup cookie
- optionally send back the response
- check if email and password exist, if one missing return 400
- find user, if no user return 401
- check password, if does not match return 401
- if everything is correct, attach cookie and send back the same response as in register
- set token cookie equal to some string value
- set expires:new Date(Date.now())
- add userController file
- export (getAllUsers,getSingleUser,showCurrentUser,updateUser,updateUserPassword) functions
- res.send('some string value')
- setup userRoutes file
- import all controllers
- setup just one route - router.route('/').get(getAllUsers);
- import userRoutes as userRouter in the app.js
- setup app.use('/api/v1/users', userRouter)
- Get all users where role is 'user' and remove password
- Get Single User where id matches id param and remove password
- If no user 404
- hardcode
- introduce params
- get user from req
- send response with user
- almost identical to login user
- add authenticateUser middleware in the route
- check for oldPassword and newPassword in the body
- if one missing 400
- look for user with req.user.userId
- check if oldPassword matches with user.comparePassword
- if no match 401
- if everything good set user.password equal to newPassword
- await user.save()
- create a file in utils (createTokenUser)
- setup a function that accepts user object and returns userToken object
- export as default
- setup all the correct imports/exports and refactor existing code
- add authenticateUser middleware in the route
- check for name and email in the body
- if one is missing, send 400 (optional)
- use findOneAndUpdate()
- create token user, attachCookiesToResponse and send back the tokenUser
- create Product.js in models folder
- create Schema
- name : {type:String}
- price: {type:Number}
- description: {type:String}
- image: {type:String}
- category: {type:String}
- company: {type:String}
- colors: {type:[]}
- featured: {type:Boolean}
- freeShipping: {type:Boolean}
- inventory:{type:Number}
- averageRating:{type:Number}
- user
- set timestamps
- export Product model
- add productController file in controllers
- export (createProduct, getAllProducts, getSingleProduct, updateProduct, deleteProduct, uploadImage) functions
- res.send('function name')
- setup productRoutes file in routes
- import all controllers
- only getAllProducts and getSingleProduct accessible to public
- rest only by admin (setup middlewares)
- typical setup
- router.route('/uploadImage').post(uploadImage)
- import productRoutes as productRouter in the app.js
- setup app.use('/api/v1/products', productRouter)
- create user property on req.body and set it equal to userId (req.user)
- pass req.body into Product.create
- send back the product
- getAllProducts
- getSingleProduct
- updateProduct
- deleteProduct
- typical CRUD, utilize (task or job) project
- remember we check already for role 'admin'
- if some question, re-watch 07-file-upload
- images folder with two images
- create Review.js in models folder
- create Schema
- rating : {type:Number}
- title: {type:String}
- comment: {type:String}
- user
- product
- set timestamps
- export Review model
- add reviewController file in controllers
- export (createReview, getAllReviews, getSingleReview, updateReview, deleteReview) functions
- res.send('function name')
- setup reviewRoutes file in routes
- import all controllers
- only getAllReviews and getSingleReview accessible to public
- rest only to users (setup middleware)
- typical REST setup
- import reviewRoutes as reviewRouter in the app.js
- setup app.use('/api/v1/reviews', reviewRouter)
- check for product in the req.body
- attach user property (set it equal to req.user.userId) on to req.body
- create review
- don't test yet
- both public routes, typical setup
- get id from req.params
- check if review exists
- if no review, 404
- check permissions (req.user, review.user)
- use await review.remove()
- send back 200
- get id from req.params
- get {rating, title comment} from req.body
- check if review exists
- if no review, 404
- check permissions
- set review properties equal to rating, title, comment
- use await review.save()
- send back 200
- create Order.js in models folder
- create Schema
- tax : {type:Number}
- shippingFee: {type:Number}
- subtotal: {type:Number}
- total: {type:Number}
- orderItems:[]
- status:{type:String}
- user
- clientSecret:{type:String}
- paymentId:{type:String}
- set timestamps
- export Order model
- add orderController file in controllers
- export (getAllOrders, getSingleOrder, getCurrentUserOrders, createOrder, updateOrder) functions
- res.send('function name')
- setup orderRoutes file in routes
- import all controllers
- authenticate user in all routes
- getAllOrders admin only
- typical REST setup
- router.route('/showAllMyOrders').get(getCurrentUserOrders)
- import orderRoutes as orderRouter in the app.js
- setup app.use('/api/v1/orders', orderRouter)
- most complex
- getAllOrders - admin only
- getSingleOrder - chechPermissions
- find orders where user is equal to req.user.userId
- get order id
- get paymentIntentId (req.body)
- get order
- if does not exist - 404
- check permissions
- set paymentIntentId and status as 'paid'
- order.save()
- [Docgen Library] (https://github.com/thedevsaddam/docgen)
- Export Postman Collection
- docgen build -i fileName.json -o index.html
- create index.html in public
- express-rate-limiter
- helmet
- xss-clean
- express-mongo-sanitize
- cors (cookies!!!!)
- [] heroku account and heroku cli
- [] remove/copy from the main repo
- [] add dev command "nodemon app.js"
- [] change start to "node app.js"
- [] setup node version in package.json
- [] "engines": {"node": "14.x"}
- [] Procfile "web: node app.js"
- [] remove existing git repo
- [] rm -rf .git - mac,
- [] git init
- [] git add .
- [] git commit -m "initial commit"
- [] heroku login
- [] heroku create "App Name"
- [] git remote -v
- [] setup env vars in GUI
- [] git push heroku master/main