I have a route of type post, that is receiving some info from the front-end, as shown below:
const router = require("express").Router();
const UsernameController = require("../controllers/username.controller");
router.post("/username", async (req, res) => {
try {
const cookie = req.cookies;
const {userName} = req.body;
let allGames = await new UsernameController().getGames(userName);
console.log(allGames[0].games)
return res.sendStatus(200)
} catch (err) {
console.log(err);
res.status(422).send(err);
};
});
module.exports = router;
I need to use the destructured {userName} = req.body in another file. So I’m wondering how I can export the {userName} received from the front-end to the middleware.js file.
middleware.js:
const AuthController = require("../controllers/auth.controller");
const UsernameController = require("../controllers/username.controller");
const usernameRouter = require('../routes/username.route')
module.exports = async (req, res, next) => {
let userName = usernameRouter.userName
const userGamesArray = await new UsernameController().getGames(userName)
req.userGamesArray = userGamesArray;
next();
};
When I console.log the userName variable in the middleware file, it responds with undefined which means I’m importing the variable wrongly from the route.js file.
Kindly assist me with importing the variable from the route.js file to the middleware.js file.
You just need to use a middleware in this /username route like this:
const middleware = require("./middleware"); // correct this path to a real one
router.post("/username", middleware, async (req, res) => {
...
Related
i need to pass a variable called path from router file lessonsRouter.js to another router file lessons.js
My folder structure
routes
|
+--lessons.js
|
+--lessonsRouter.js
lessonsRouter.js
const router = require('express').Router();
const lessons = require('./lessons');
router.get('/*/([A-Z][a-z]+)/README.md', (req, res) => {
const path = req.url; // the variable that i need to pass to lessons.js router
// ignore next three lines
const pathSeparate = req.url.split('/');
const LessonTopic = pathSeparate[1].toLowerCase()
const LessonName = pathSeparate[2].match(/[A-Z][a-z]+/g).join('-').toLowerCase();
res.locals.path = path;
res.redirect(`/lessons/${LessonTopic}/${LessonName}`);
});
router.use('/:topic/:name', lessons);
module.exports = router;
lessons.js
const router = require('express').Router();
router.get('/', (req, res) => {
// i want to use variable path from lessonsRouter.js here
});
module.exports = router;
I would argue that you have your dependency/import direction wrong. lessons should import from lessonsRouter. But if you really want it this way, then you can export a function to which you can pass the path once you have it.
lessonsRouter.js
const lessons = require('./lessons');
router.get('/*/([A-Z][a-z]+)/README.md', (req, res) => {
const path = req.url; // the variable that i need to pass to lessons.js router
lessons(path);
...
});
lessons.js
module.exports = (path) => {
router.get('/', (req, res) => {
console.log(path);
});
};
I'm creating an restAPI and I'm not getting the express.Router () delete method to work
I'm looking for answers but all the answers I find are in line with what I did.
Only the delete method does not work, the others are OK.
Routes file:
const express = require('express')
const CustumerController = require('../controllers/CustumerController')
const router = express.Router()
router.get('/customers', CustumerController.index)
router.get('/customers/:id', CustumerController.show)
router.post('/customers', CustumerController.store)
router.delete('/customers/:id', CustumerController.destroy)
module.exports = router
CustumerController.js
async destroy(req, res) {
const { id } = req.params
const result = await CustomerRepository.delete(req)
res.json(result)
}
CustomerRepository.js
async destroy(id) {
const clause = {
where: { id }
}
try {
return await Customers.destroy(clause)
} catch (err) {
return {
statusCode: status.INTERNAL_SERVER_ERROR,
message: status.classes['5XX_MESSAGE'],
error: err
}
}
}
example of the error in delete:
example of the success, in get
I've tried, on the controller, to fire res.json () with a simple object, just for testing, but it didn't work, the request is not enough.
The problem seems to be really in the delete method of express.Router
I thank you for your help
the router is well programmed the problem has it in the endpoint response I recommend using try catch to analyze the error in detail
Everything is alright in your code, no need to change anything. debug it, first try to return static response on delete api instead of deleting a data from db. Then only you will get to know about the issue.
Your get request also should not work! You named your controller CostumerController in this line:
const CostumerController = require('../controllers/CostumerController')
And used CustumerController. I used your code and everything works correctly.
index.js
const express = require('express');
const router = require('./router');
const app = express();
app.use(router);
app.listen(8000, () => {
console.log('Server started.')
});
CustomerController.js
module.exports = {
destroy: (req, res) => {
res.status(200).send('destroy');
},
index: (req, res) => {
res.status(200).send('index');
},
show: (req, res) => {
res.status(200).send('show');
},
store: (req, res) => {
res.status(200).send('store');
}
}
And router.js
const express = require('express')
const CustomerController = require('./CustomerController')
const router = express.Router()
router.get('/customers', CustomerController.index)
router.get('/customers/:id', CustomerController.show)
router.post('/customers', CustomerController.store)
router.delete('/customers/:id', CustomerController.destroy)
module.exports = router;
I have making an API using express and node.
Here is my app.js
const express = require('express');
const bodyParser = require('body-parser');
const dotenv = require('dotenv');
// setup dotenv to read environment variables
dotenv.config()
// Load Environment Varibles
const env = require('./utils/env');
// INIT MONGODB CONNECTION
require('./mongoose');
// create a new express application
const app = express();
// setup bodyparser middleware to read request body in requests
// we're only reading JSON inputs
app.use(bodyParser.json());
// Listen to API routes
const apiRoutes = require('./routes')
app.use('/api', apiRoutes);
// Start listening to requests
app.listen(env.PORT, () => {
console.log(`Server started on PORT ${env.PORT}`);
});
And here is the API routes that are being imported
const express = require('express');
const apiController = require('./apiController');
const apiValidator = require('./apiValidator');
const router = express.Router();
router.post('/login', apiValidator.loginUserValidator, apiController.loginUserController);
router.get('/rand', (req, res) => {
res.send('Some randon text');
});
module.exports = router;
Here is the middleware
const {
failureResponse
} = require('./../utils/response');
const errorcodes = require('./../utils/errorcodes');
const loginUserValidator = (req, res, next) => {
const user = req.body;
if (!user.username) {
return res.status(400).json(failureResponse(errorcodes.ERROR_INVALID_BODY_PARAMETER, "Invalid username"));
}
if (!user.password) {
return res.status(400).json(failureResponse(errorcodes.ERROR_INVALID_BODY_PARAMETER, "Invalid password"));
}
if (user.authTokens) {
delete user.authTokens;
}
next();
};
module.exports = {
loginUserValidator
};
Here is the controller
const User = require('./../models/user');
const {
successResponse,
failureResponse
} = require('./../utils/response');
const errorcodes = require('./../utils/errorcodes');
const loginUserController = async (req, res) => {
try {
const user = req.body;
// find if the user already exists
const existingUser = await User.findOne({
username: user.username
});
if (existingUser) {
// user exists. generate token and login user
console.log('Existing user login');
const token = existingUser.generateAuthToken();
return res.status(200).json(successResponse(token));
} else {
console.log('New user login');
const savedUser = await new User(user).save();
const token = savedUser.generateAuthToken();
return res.status(200).json(successResponse(token));
}
} catch (e) {
console.log(e);
return res.status(400).json(failureResponse(errorcodes.ERROR_SERVER_ERROR, "Unable to login user"));
}
};
module.exports = {
loginUserController
};
Here the issue is when I try to hit the login route from Postman, I am getting an error which says Could not get any response.
But when I hit the rand route, the output is correct.
So the issue isn't the arrangement of the code.
Why am I not able to use the login route here?
I have set up express to use the following paths:
const profile = require("./api/profile")
const events = require("./api/events")
app.use("/api/events", events)
app.use("/api/profile", profile)
Inside the events and profile index.js files I have the following:
const router = require('./../../modules/router.js')
router.get('/', (req, res) => {
})
module.exports = router
My router.js file:
const express = require("express")
const cookieParser = require('cookie-parser')()
const cors = require('cors')({origin: true})
const router = express.Router()
const firebase = require("./firebase.js")
// https://github.com/firebase/functions-samples/tree/master/authorized-https-endpoint
// Must have header 'Authorization: Bearer <Firebase ID Token>'
const validateFirebaseIdToken = (req, res, next) => {
if ((!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) &&
!req.cookies.__session) {
res.status(403).send({ "error": 'Unauthorized'})
return
}
let idToken
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) {
// Read the ID Token from the Authorization header.
idToken = req.headers.authorization.split('Bearer ')[1]
} else {
// Read the ID Token from cookie.
idToken = req.cookies.__session
}
firebase.admin.auth().verifyIdToken(idToken).then((decodedIdToken) => {
req.user = decodedIdToken
return next()
}).catch(error => {
res.status(403).send({"error": 'Unauthorized'})
})
}
router.use(cors)
router.use(cookieParser)
router.use(validateFirebaseIdToken)
module.exports = router
For some reason, the router mixes up the paths /api/events/ and /api/profile/ whenever I call them. For all other paths it works fine. How can I stop this from happening?
If you are using the same router for both events and profile, it could be the source of your issue.
Have you tested to create one router for each module?
Maybe try something like this for both events and profile:
const router = require('express').Router()
router.get('/', (req, res) => {
})
module.exports = router
For example, in Meteor, there's something like
Router.plugin('ensureSignedIn');
Router.plugin('ensureSignedIn', {
except: ['home', 'atSignIn', 'atSignUp', 'atForgotPassword']
});
So unsigned user cannot access other routes except above four.
How to do this in express.js? I'm using passport.js also.
I'm not familiar with Meteor, but you can do something like the following, assuming you want to make pages available to only authenticated users (passport).
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated())
return next();
else
// Return error content: res.jsonp(...) or redirect: res.redirect('/login')
}
app.get('/account', ensureAuthenticated, function(req, res) {
// Do something with user via req.user
});
The ensureAuthenticated function is just an example, you can define your own function. Calling next() continues the request chain.
I should use middleware for protect my routes, even to protect certain verbs in the same route:
for example: in my endpoint/route.js
// the require sentences are omitted
const express = require('express');
const { /*controllerFunctions*/ } = require('./controller');
const {routeGuard} = require('/*must create a route guard*/');
const router = express.Router();
router.route('')
.get(getAllResources)
;
router.route('/:id') //
.get(validateParam,getOneResource);
router.use(routeGuard);
router.route('/:id')
.post(validateParam,validateBody,postResource)
.patch(validateParam,validateBody,patchProblemById)
.delete(validateParam,deleteResource)
;
module.exports = router;
and my routeGuard file should be like this:
const { promisify } = require('util');
const jwt = require("jsonwebtoken");
const AppError = require('./appError');
const {User} = require('./../endpoints/users/model');
const wrapper = require('./try-wrapper');//try catch wrapper
module.exports.routeGuard = wrapper(async function (req, res, next){
// the err message is the same on purpose
const notAllowed = new AppError('Unauthorized: Invalid or Nonexistent credentials',401);
let token = null;
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')){
token = req.headers.authorization.split(' ')[1];
}
if (!token) return next(notAllowed );
const payload = await promisify(jwt.verify)(token,process.env.KEY);
const user = await User.findById(payload.id);
if (!user) return next( notAllowed);
if ( ! user.hasSamePasswordSince(payload.iat) )return next( notAllowed );
req.user = user; // further use...
next();
});