diff --git a/04-store-api/starter/populate.js b/04-store-api/starter/populate.js index 79d94c0031..fbcfe2a7c2 100644 --- a/04-store-api/starter/populate.js +++ b/04-store-api/starter/populate.js @@ -1,21 +1,21 @@ -require('dotenv').config() - -const connectDB = require('./db/connect') -const Product = require('./models/product') - -const jsonProducts = require('./products.json') - -const start = async () => { - try { - await connectDB(process.env.MONGO_URI) - await Product.deleteMany() - await Product.create(jsonProducts) - console.log('Success!!!!') - process.exit(0) - } catch (error) { - console.log(error) - process.exit(1) - } -} - -start() +require('dotenv').config() + +const connectDB = require('./db/connect') +const Product = require('./models/product') + +const jsonProducts = require('./products.json') + +const start = async () => { + try { + await connectDB(process.env.MONGO_URI) + await Product.deleteMany() + await Product.create(jsonProducts) + console.log('Success!!!!') + process.exit(0) + } catch (error) { + console.log(error) + process.exit(1) + } +} + +start() diff --git a/05-JWT-Basics/starter/app.js b/05-JWT-Basics/starter/app.js index f0af6dccac..f0f095e23b 100644 --- a/05-JWT-Basics/starter/app.js +++ b/05-JWT-Basics/starter/app.js @@ -4,6 +4,7 @@ require('express-async-errors'); const express = require('express'); const app = express(); +const mainRouter = require('./routes/main'); const notFoundMiddleware = require('./middleware/not-found'); const errorHandlerMiddleware = require('./middleware/error-handler'); @@ -11,6 +12,8 @@ const errorHandlerMiddleware = require('./middleware/error-handler'); app.use(express.static('./public')); app.use(express.json()); +app.use('/api/v1', mainRouter); + app.use(notFoundMiddleware); app.use(errorHandlerMiddleware); diff --git a/05-JWT-Basics/starter/controllers/main.js b/05-JWT-Basics/starter/controllers/main.js index e69de29bb2..2fdcd7079b 100644 --- a/05-JWT-Basics/starter/controllers/main.js +++ b/05-JWT-Basics/starter/controllers/main.js @@ -0,0 +1,33 @@ +const jwt = require('jsonwebtoken'); +const { BadRequestError } = require('../errors'); + +const login = async (req, res) => { + const { username, password } = req.body; + + if (!username || !password) { + throw new BadRequestError('Please provide email and password'); + } + + // just for demo, normally provided by DB + const id = new Date().getDate(); + + //try to keep payload small, better experience for user + const token = jwt.sign({ id, username }, process.env.JWT_SECRET, { + expiresIn: '30d', + }); + + res.status(200).json({ msg: 'user created', token }); +}; + +const dashboard = async (req, res) => { + const luckyNumber = Math.floor(Math.random() * 100); + res.status(200).json({ + msg: `Hello, ${req.user.username}`, + secret: `Here is your authorized data, your lucky number is ${luckyNumber}`, + }); +}; + +module.exports = { + login, + dashboard, +}; diff --git a/05-JWT-Basics/starter/errors/bad-request.js b/05-JWT-Basics/starter/errors/bad-request.js new file mode 100644 index 0000000000..8adaddea98 --- /dev/null +++ b/05-JWT-Basics/starter/errors/bad-request.js @@ -0,0 +1,10 @@ +const CustomAPIError = require('./custom-error'); +const { StatusCodes } = require('http-status-codes'); +class BadRequest extends CustomAPIError { + constructor(message) { + super(message); + this.statusCode = StatusCodes.BAD_REQUEST; + } +} + +module.exports = BadRequest; diff --git a/05-JWT-Basics/starter/errors/custom-error.js b/05-JWT-Basics/starter/errors/custom-error.js index 070a84903b..c202507637 100644 --- a/05-JWT-Basics/starter/errors/custom-error.js +++ b/05-JWT-Basics/starter/errors/custom-error.js @@ -1,8 +1,7 @@ class CustomAPIError extends Error { - constructor(message, statusCode) { - super(message) - this.statusCode = statusCode + constructor(message) { + super(message); } } -module.exports = CustomAPIError +module.exports = CustomAPIError; diff --git a/05-JWT-Basics/starter/errors/index.js b/05-JWT-Basics/starter/errors/index.js new file mode 100644 index 0000000000..36c6f80198 --- /dev/null +++ b/05-JWT-Basics/starter/errors/index.js @@ -0,0 +1,9 @@ +const CustomAPIError = require('./custom-error'); +const BadRequestError = require('./bad-request'); +const UnauthenticatedError = require('./unauthenticated'); + +module.exports = { + CustomAPIError, + BadRequestError, + UnauthenticatedError, +}; diff --git a/05-JWT-Basics/starter/errors/unauthenticated.js b/05-JWT-Basics/starter/errors/unauthenticated.js new file mode 100644 index 0000000000..1e07b5a166 --- /dev/null +++ b/05-JWT-Basics/starter/errors/unauthenticated.js @@ -0,0 +1,11 @@ +const CustomAPIError = require('./custom-error'); +const { StatusCodes } = require('http-status-codes'); + +class UnauthenticatedError extends CustomAPIError { + constructor(message) { + super(message); + this.statusCode = StatusCodes.UNAUTHORIZED; + } +} + +module.exports = UnauthenticatedError; diff --git a/05-JWT-Basics/starter/middleware/auth.js b/05-JWT-Basics/starter/middleware/auth.js index e69de29bb2..7254623b26 100644 --- a/05-JWT-Basics/starter/middleware/auth.js +++ b/05-JWT-Basics/starter/middleware/auth.js @@ -0,0 +1,22 @@ +const jwt = require('jsonwebtoken'); +const { UnauthenticatedError } = require('../errors'); + +const authenticationMiddleware = async (req, res, next) => { + const authHeader = req.headers.authorization; + if (!authHeader || !authHeader.startsWith('Bearer ')) { + throw new UnauthenticatedError('No token provided'); + } + + const token = authHeader.split(' ')[1]; + + try { + const decoded = jwt.verify(token, process.env.JWT_SECRET); + const { id, username } = decoded; + req.user = { id, username }; + next(); + } catch (error) { + throw new UnauthenticatedError('Not autorized to acces this route'); + } +}; + +module.exports = authenticationMiddleware; diff --git a/05-JWT-Basics/starter/middleware/error-handler.js b/05-JWT-Basics/starter/middleware/error-handler.js index ac13bda4ad..0baebcfcb8 100644 --- a/05-JWT-Basics/starter/middleware/error-handler.js +++ b/05-JWT-Basics/starter/middleware/error-handler.js @@ -1,9 +1,12 @@ -const CustomAPIError = require('../errors/custom-error') +const { CustomAPIError } = require('../errors'); +const { StatusCodes } = require('http-status-codes'); const errorHandlerMiddleware = (err, req, res, next) => { if (err instanceof CustomAPIError) { - return res.status(err.statusCode).json({ msg: err.message }) + return res.status(err.statusCode).json({ msg: err.message }); } - return res.status(500).send('Something went wrong try again later') -} + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send('Something went wrong try again later'); +}; -module.exports = errorHandlerMiddleware +module.exports = errorHandlerMiddleware; diff --git a/05-JWT-Basics/starter/routes/main.js b/05-JWT-Basics/starter/routes/main.js index e69de29bb2..706b8744ab 100644 --- a/05-JWT-Basics/starter/routes/main.js +++ b/05-JWT-Basics/starter/routes/main.js @@ -0,0 +1,11 @@ +const express = require('express'); +const router = express.Router(); + +const { login, dashboard } = require('../controllers/main'); + +const authMiddleware = require('../middleware/auth'); + +router.route('/dashboard').get(authMiddleware, dashboard); +router.route('/login').post(login); + +module.exports = router;