UnhandledPromiseRejectionWarning - UnhandledPromiseRejectionWarning - DeprecationWarning - javascript

I am getting this error ->
(node:18420) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'name' of undefined
at C:\Users\ohrid\Desktop\backend2\routes\categories.js:27:24
at Layer.handle [as handle_request] (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:317:13)
at C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\ohrid\Desktop\backend2\node_modules\express\lib\router\index.js:275:10)
at logger (C:\Users\ohrid\Desktop\backend2\node_modules\morgan\index.js:144:5)
(node:18420) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:18420) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
My routes/categories.js:
const { Category } = require('../models/category')
const express = require('express')
const router = express.Router()
router.get(`/`, async (req, res) => {
const categoryList = await Category.find()
if (!categoryList) {
res.status(500).json({ success: false })
}
res.status(200).send(categoryList)
})
router.get('/:id', async (req, res) => {
const category = await Category.findById(req.params.id)
if (!category) {
res.status(500).json({
message: 'The category with the given ID was not found.',
})
}
res.status(200).send(category)
})
router.post('/', async (req, res) => {
let category = new Category({
name: req.body.name,
icon: req.body.icon,
color: req.body.color,
})
category = await category.save()
if (!category)
return res.status(400).send('the category cannot be created!')
res.send(category)
})
router.put('/:id', async (req, res) => {
const category = await Category.findByIdAndUpdate(
req.params.id,
{
name: req.body.name,
icon: req.body.icon || category.icon,
color: req.body.color,
},
{ new: true }
)
if (!category)
return res.status(400).send('the category cannot be created!')
res.send(category)
})
router.delete('/:id', (req, res) => {
Category.findByIdAndRemove(req.params.id)
.then((category) => {
if (category) {
return res
.status(200)
.json({
success: true,
message: 'the category is deleted!',
})
} else {
return res
.status(404)
.json({ success: false, message: 'category not found!' })
}
})
.catch((err) => {
return res.status(500).json({ success: false, error: err })
})
})
module.exports = router
My app.js
const express = require('express')
const app = express()
const morgan = require('morgan')
const mongoose = require('mongoose')
const cors = require('cors')
const dotenv = require('dotenv')
require('dotenv/config')
app.use(cors())
app.options('*', cors())
//middleware
app.use(morgan('tiny'))
//Routes
const categoriesRoutes = require('./routes/categories')
const productsRoutes = require('./routes/products')
const usersRoutes = require('./routes/users')
const ordersRoutes = require('./routes/orders')
const api = process.env.API_URL
app.use(`${api}/categories`, categoriesRoutes)
app.use(`${api}/products`, productsRoutes)
app.use(`${api}/users`, usersRoutes)
app.use(`${api}/orders`, ordersRoutes)
mongoose
.connect(
'mongodb+srv://dani:Luka5678#cluster0.23wee.mongodb.net/e-shop?retryWrites=true&w=majority',
{
useNewUrlParser: true,
useUnifiedTopology: true,
dbName: 'e-shop',
}
)
.then(() => {
console.log('Database connection is ready')
})
.catch((err) => {
console.log(err)
})
app.listen(4000, () => {
console.log('server is running on http://localhost:4000')
})
What should I change?

You don't have any error handling layer in your application.
If you use Express v5 and above, route handlers and middleware that return a Promise will catch the errors and will call next(value) automatically.
Otherwise, from asynchronous functions, you must pass them to the next() function, where Express will catch and process them.
That way, you won't get the UnhandledPromiseRejectionWarning.

Related

UnhandledPromiseRejectionWarning: TypeError: UserService.authenticate is not a function

im trying to implement a basic auth to my api project with knex express and mysql.
i have the following functions
const users = [{ id:1, username:'selia', password:'fullservice'}]
function authenticate({ username, password}) {
const user = users.find(u => u.username === username && u.password === password)
if(user) {
const {password, ...userWithoutPassword} = user
return userWithoutPassword
}
}
module.exports = authenticate
and
const userService = require('../users/user.service.js')
async function basicAuth(req,res,next){
// checando basic auth
if(!req.headers.authorization || req.headers.authorization.indexOf('Basic') === -1) {
return res.status(403).json({ message: 'Header de Autorizacao nao encontrado'})
}
//verificando basuc auth
const base64Credentials = req.headers.authorization.split('')[1]
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii')
const [username, password] = credentials.split(':')
const user = await userService.authenticate({ username, password})
if (!user){
return res.status(403).json({ message: 'Usuario e/ou senha invalidos'})
}
//atribuindo usuario no objeto da requisicao
req.user = user
next();
}
module.exports = basicAuth
and this is my index
const express = require('express')
const routes = require('./routes')
const basicAuth = require('./helpers/basic-auth')
const app = express()
app.use(basicAuth)
app.use(routes)
app.listen(3333, ()=> console.log('Server is running'))
when i run it i get this error
(node:7488) UnhandledPromiseRejectionWarning: TypeError: userService.authenticate is not a function
at basicAuth (/home/matheus/projeto/src/helpers/basic-auth.js:18:30)
at Layer.handle [as handle_request] (/home/matheus/projeto/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/matheus/projeto/node_modules/express/lib/router/index.js:317:13)
at /home/matheus/projeto/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/matheus/projeto/node_modules/express/lib/router/index.js:335:12)
at next (/home/matheus/projeto/node_modules/express/lib/router/index.js:275:10)
at expressInit (/home/matheus/projeto/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/home/matheus/projeto/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/matheus/projeto/node_modules/express/lib/router/index.js:317:13)
at /home/matheus/projeto/node_modules/express/lib/router/index.js:284:7
(node:7488) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:7488) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
i get this error when i do a get request on insomnia
i belive that this has to do with my async function but i cant figure out how to fix that
sorry for my bad english
Considering how you exported and imported the function, this line is not correct:
const user = await userService.authenticate({ username, password})
It should just be:
const user = await userService({ username, password})
Because your user.service.js module exports a function, NOT an object with an authenticate property.

Unhandled promise error in Node and Express

I was making CRUD APIs with NodeJS, ExpressJS, and Mongoose, on executing the following code I got an UnhandledPromiseRejectionWarning error for line number 29. Despite having a try-catch block.
Code:
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
require('../src/db/conn.js');
const MensRanking = require('../src/models/mens.js');
app.use(express.json());
app.get('/', async (req, res) =>{
res.send("<h1>Hello World!</h1>");
})
app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.sendStatus(201).send(insert);
}
catch(e){
res.sendStatus(400).send(e);
}
})
app.get('/mens', async (req, res) =>{
try{
const getMens = await MensRanking.find({});
res.sendStatus(201).send(getMens);
}
catch(e){
res.sendStatus(400).send(e);
}
})
app.listen(port,()=>{
console.log(`\nlistening at http://127.0.0.1:${port}\n`);
})
Error:
(node:20016) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:518:11)
at ServerResponse.header (D:\projects\rest-api-sections\rest-tute\node_modules\express\lib\response.js:771:10)
at ServerResponse.contentType (D:\projects\rest-api-sections\rest-tute\node_modules\express\lib\response.js:599:15)
at ServerResponse.sendStatus (D:\projects\rest-api-sections\rest-tute\node_modules\express\lib\response.js:357:8)
at D:\projects\rest-api-sections\rest-tute\src\app.js:29:13
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:20016) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:20016) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Here is the complete code repository
You should use res.status instead of sendStatus
Difference between response.status() vs. response.sendStatus() in express
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
require('../src/db/conn.js');
const MensRanking = require('../src/models/mens.js');
app.use(express.json());
app.get('/', async (req, res) => {
res.send('<h1>Hello World!</h1>');
});
app.post('/mens', async (req, res) => {
try {
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.status(201).send(insert);
}
catch (e) {
res.status(400).send(e);
}
});
app.get('/mens', async (req, res) => {
try {
const getMens = await MensRanking.find({});
res.status(201).send(getMens);
}
catch (e) {
res.status(400).send(e);
}
});
app.listen(port, () => {
console.log(`\nlistening at http://127.0.0.1:${port}\n`);
});
You are using sendStatus function of epxress.js as it immediately sends that particular assigned code to the response object which triggers response before your data is set, so when your send function is called response object has already been sent, hence the error:
Cannot set headers after they are sent to the client
Instead, use this when you need to set HTTP Response codes as well alongside data
res.status(RESPONSE_CODE).send(DATA)
There are two problematic function in this case i just highlight one, because they have the same errors:
app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.sendStatus(201).send(insert);
}
catch(e){
res.sendStatus(400).send(e);
}})
You already sent a response in your try-block with res.sendStatus(201) and trying to send again with .send(insert) -> throws exception
After that you do the same error again with res.sendStatus(400).send(e);
The following code should do what you tried to intend:
app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.status(201).send(insert);
}
catch(e){
res.status(400).send(e);
}})

Next.js - TypeError fn is not a function

Inside my routes/index.js file I have:
const express = require("express");
const authController = require("../controllers/authController");
const router = express.Router();
console.log('ROUTES index.js')
/* Error handler for async / await functions */
const catchErrors = fn => {
return function(req, res, next) {
return fn(req, res, next).catch(next);
};
};
/**
* AUTH ROUTES: /api/auth
*/
router.post(
"/api/auth/signup",
authController.validateSignup,
catchErrors(authController.signup)
);
module.exports = router;
and then inside the authController.js I have:
const { body, check, sanitizeBody, validationResult } = require('express-validator');
exports.validateSignup = async (req, res, next) => {
console.log('validateSignup')
await check("name").notEmpty().withMessage("Enter a Name")
.isLength({ min: 4, max: 10 }).withMessage("Name must be between 4 and 10 characters").run(req);
const result = validationResult(req);
if (!result.isEmpty()) {
console.log('inside if of validateSignup')
return res.status(400).json({ errors: result.array() });
}
console.log('before next')
next();
};
I then use axios to post to that specified route:
const { data } = await axios.post("/api/auth/signup", user);
With the above line if I enter the correct inputs I don't get any errors and therefore the console.log inside the if statement is not called... but I get the following output and errors:
validateSignup
before next
TypeError: fn is not a function
at /Users/bliss/Documents/Coder/NextJS/NextManilaBNB/server/routes/index.js:14:16
at Layer.handle [as handle_request] (/Users/bliss/Documents/Coder/NextJS/NextManilaBNB/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/bliss/Documents/Coder/NextJS/NextManilaBNB/node_modules/express/lib/router/route.js:137:13)
at exports.validateSignup (/Users/bliss/Documents/Coder/NextJS/NextManilaBNB/server/controllers/authController.js:23:5)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
As you can see the error seems to happen after calling next()
How to solve this?
What is causing this?

Problem with .json as request response in NodeJS

I am developing a backend with a database in mongoDB, when defining an endpoint of type post and testing it in postman it sends me an error in the console and in postman I do not get the object that I defined as a response to the post, however if it performs the incersion correctly in the database
this is the route
/*
/api/hospitales
*/
const { Router } = require('express');
const { check } = require('express-validator');
const {
getHospitales,
crearHospital,
actualizarHospital,
eliminarHospital
} = require('../controller/hospitales_controller');
const { validarCampos } = require('../middlewares/validarCampos_middleware');
const { validarJWT } = require('../middlewares/validarJWT_middleware');
const router = Router();
router.get('/', [], getHospitales);
router.post('/', [
validarJWT,
check('nombre', 'El nombre del hospital es necesario').not().isEmpty(),
validarCampos
], crearHospital);
router.put('/:id', [], actualizarHospital);
router.delete('/:id', [], eliminarHospital);
module.exports = router;
this is the controller
const { response } = require('express');
const Hospital = require('../model/hospitales_model');
const crearHospital = async(req, res = response) => {
const uid = req.uid;
const hospital = new Hospital({
usuario: uid,
...req.body
});
try {
const hospitalDB = await hospital.save();
res.json({
ok: true,
hospital: hospitalDB
});
} catch (error) {
console.log(error);
res.status(500).json({
ok: false,
msg: 'Hable con el administrador'
});
}
};
This is the model
const { Schema, model } = require('mongoose');
const HospitalSchema = Schema({
nombre: {
type: String,
required: true
},
img: {
type: String,
},
usuario: {
required: true,
type: Schema.Types.ObjectId,
ref: 'Usuario'
}
}, { collection: 'Hospitales' });
HospitalSchema.method('toJSON', function() {
const { __v, ...object } = this.toObject();
return object;
});
module.exports = model('Hospital', HospitalSchema);
this is the error in console
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:536:11)
at ServerResponse.header (Z:\NODE\N_BackEndAdminPro\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (Z:\NODE\N_BackEndAdminPro\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (Z:\NODE\N_BackEndAdminPro\node_modules\express\lib\response.js:267:15)
at crearHospital (Z:\NODE\N_BackEndAdminPro\controller\hospitales_controller.js:24:13)
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
code: 'ERR_HTTP_HEADERS_SENT'
}
(node:14752) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:536:11)
at ServerResponse.header (Z:\NODE\N_BackEndAdminPro\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (Z:\NODE\N_BackEndAdminPro\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (Z:\NODE\N_BackEndAdminPro\node_modules\express\lib\response.js:267:15)
at crearHospital (Z:\NODE\N_BackEndAdminPro\controller\hospitales_controller.js:31:32)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:14752) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:14752) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
this is the result in postman
Solved, Like many of the code problems that exist it was simply an extra call of the next() function in the validateJWT middleware that accompanies the request
bad code
const jwt = require('jsonwebtoken');
const validarJWT = (req, res, next) => {
//leer token
const token = req.header('x-token');
if (!token) {
return res.status(401).json({
ok: false,
msg: 'No hay token en la peticion'
});
}
try {
const { uid } = jwt.verify(token, process.env.JWT_SECRET);
req.uid = uid;
next();
} catch (error) {
return res.status(401).json({
ok: false,
msg: 'Token invalido'
});
}
next();
};
rigth code
const jwt = require('jsonwebtoken');
const validarJWT = (req, res, next) => {
//leer token
const token = req.header('x-token');
if (!token) {
return res.status(401).json({
ok: false,
msg: 'No hay token en la peticion'
});
}
try {
const { uid } = jwt.verify(token, process.env.JWT_SECRET);
req.uid = uid;
} catch (error) {
return res.status(401).json({
ok: false,
msg: 'Token invalido'
});
}
next();
};

Express: [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I have read through several posts regarding this same issue but I cannot figure out where I am initially sending the headers. Here is the stack trace:
Also seems weird that I am getting a 204 as it adds to the db, and then it spits out a 404. Clearly something is wrong, but i'm simply not seeing it.
I've tried adding returns to every res.json() statement.
OPTIONS /api/users/favorites 204 1.822 ms - 0
PATCH /api/users/favorites 404 19.769 ms - 160
Unhandled rejection Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:455:11)
at ServerResponse.header (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/response.js:771:10)
at ServerResponse.send (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/response.js:267:15)
at /Users/beers/projects/node/cryptopal-api/src/users/usersRouter.js:30:38
From previous event:
at Builder.Target.then (/Users/beers/projects/node/cryptopal-api/node_modules/knex/lib/interface.js:27:24)
at /Users/beers/projects/node/cryptopal-api/src/users/usersRouter.js:19:8
at Layer.handle [as handle_request] (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/route.js:137:13)
at requireAuth (/Users/beers/projects/node/cryptopal-api/src/middleware/jwt-auth.js:31:5)
at Layer.handle [as handle_request] (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/layer.js:95:5)
at /Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:335:12)
at next (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:174:3)
at router (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:317:13)
at /Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:335:12)
at next (/Users/beers/projects/node/cryptopal-api/node_modules/express/lib/router/index.js:275:10)
at /Users/beers/projects/node/cryptopal-api/node_modules/body-parser/lib/read.js:130:5
at invokeCallback (/Users/beers/projects/node/cryptopal-api/node_modules/raw-body/index.js:224:16)
at done (/Users/beers/projects/node/cryptopal-api/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/Users/beers/projects/node/cryptopal-api/node_modules/raw-body/index.js:273:7)
at IncomingMessage.emit (events.js:205:15)
at endReadableNT (_stream_readable.js:1154:12)
here is my usersRouter.js
require('dotenv').config();
const express = require('express');
// const rp = require('request-promise');
const usersRouter = express.Router()
const jsonParser = express.json()
const UsersService = require('./usersService.js')
const { requireAuth } = require('../middleware/jwt-auth.js')
usersRouter
.patch('/favorites', requireAuth, (req,res,next) => {
const db = req.app.get('db');
const { coinID } = req.body;
const { user_id } = req;
console.log(res.headersSent) // EQUALS FALSE
// get current favorites for user to see if it already exists in db
UsersService.getUserFavorites(db, user_id)
.then( response => {
console.log(res.headersSent) // EQUALS TRUE
let favExists = false;
response.favorites.forEach( fav => {
if(fav == coinID)
favExists = true;
})
if(favExists){
return res.status(401).json({ error: "Coin already exists in favorites" })
}else{
UsersService.addToUserFavorites(db, user_id, coinID)
.then( response => {
return res.status(204).json({ response })
})
}
})
next()
});
module.exports = usersRouter;
As you can see, the patch route calls a middleware function requireAuth to authenticate a user before it will add a favorite.
Here is that file jwt-auth.js
const AuthService = require('../auth/authService.js')
function requireAuth(req, res, next) {
const authToken = req.get('Authorization') || ''
let bearerToken
if (!authToken.toLowerCase().startsWith('bearer ')) {
return res.status(401).json({ error: 'Missing bearer token' })
} else {
bearerToken = authToken.slice(7, authToken.length)
}
try {
const payload = AuthService.verifyJwt(bearerToken);
AuthService.getUserByEmail(
req.app.get('db'),
payload.sub,
)
.then(user => {
if (!user){
return res.status(401).json({ error: 'Unauthorized request' })
}
next();
})
.catch(err => {
console.error(err)
next(err)
})
req.user_id = payload.user_id;
next()
} catch(error) {
return res.status(401).json({ error: 'Unauthorized request' })
}
}
module.exports = {
requireAuth,
}
I will include the usersService.js and authService.js files as well because a couple functions are called within them, but I don't believe thats where the error lies.
usersService.js:
const xss = require('xss');
const config = require('../config.js');
const UsersService = {
getUserByID(db,id){
return db('cryptopal_users')
.where({ id })
.first()
},
getUserFavorites(db,id){
return db('cryptopal_users')
.where('id', id)
.first()
},
addToUserFavorites(db,id,favorites){
return db('cryptopal_users')
.where('id', id)
.update({
favorites: db.raw('array_append(favorites, ?)', [favorites])
})
},
}
module.exports = UsersService;
authService.js
const xss = require('xss');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('../config.js');
const AuthService = {
validatePassword(password){
if(password.length < 6){
return "Password must be at least 6 characters"
}
},
hashPassword(password){
return bcrypt.hash(password,12);
},
comparePasswords(password,hash){
return bcrypt.compare(password,hash);
},
createJwt(subject, payload) {
return jwt.sign(payload, config.JWT_SECRET, {
subject,
expiresIn: config.JWT_EXPIRY,
algorithm: 'HS256',
})
},
checkEmailUnique(db,email){
return db('cryptopal_users')
.where({ email })
.first()
.then(user => !!user)
},
insertUser(db,user){
return db
.insert(user)
.into('cryptopal_users')
.returning('*')
.then( ([user]) => user )
},
serializeUser(user){
return {
id: user.id,
name: xss(user.name),
email: xss(user.email),
date_created: new Date(user.date_created),
}
},
getUserByEmail(db,email){
return db('cryptopal_users')
.where({ email })
.first()
},
verifyJwt(token) {
return jwt.verify(token, config.JWT_SECRET, {
algorithms: ['HS256'],
})
},
}
module.exports = AuthService;
I believe the issue lies somewhere within the jwt-auth.js file, but not 100% sure. The code does get all the way through to the end and it inserts the favorite into the database after authenticating the users, but then throws an error about the headers.
the problem was that at the very end of the patch route, I had a next(). Once i removed that, it worked fine.

Categories

Resources