I am not sure if this is a Mongoose or Nodejs Express error?
I would just like to know if there is a way to add middleware in the form of an if. This is my call:
app.post(pPath, auth, (req, res) => {
...
})
And I would just like to do something like this:
app.post(pPath, varBoolean ? auth : null, (req, res) => {
...
})
The above example does not work though. Any idea how I can do this?
Express methods don't support non-function handlers. This is generally a good thing because this allows to detect problems with imports on application start.
This can be achieved with a spread:
app.post(...[pPath, varBoolean && auth, (req, res) => {
...
}].filter(Boolean))
You should try using 'app.use', if you want to have a middleware in place.
app.use('/path', (req, res, next) => {
const { test } = req.body;
const { auth } = req.headers;
if(!test) {
return res.status(400).json({message: 'Missing field test'});
}
const validToken = await tokenValidation(auth);
if(!validToken){
return res.status(403).json({message: 'Unauthorized'});
}
next();
});
Related
Running NodeJS on Ubuntu 20.04.2, using VSApp with the debugger
I have the following file named /src/routes/regions.js:
const router = require('express').Router()
const { int } = require('neo4j-driver')
const { required, optional } = require('../middleware/auth')
const { check } = require('express-validator')
const validate = require('../middleware/validate')
const neo4j = require('../neo4j')
const Joi = require('joi');
const Region = require('../entities/Region')
router.get('/1', (req, res, next) => {
return req.neo4j.read(`
MATCH (regions:Region)
return regions order by regions.name ASC
`, params)
.then(regions => res.send(regions))
.catch(e => next(e))
})
router.get('/', (req, res, next) => {
return req.neo4j.read(`
MATCH (regions:Region)
return regions order by regions.name DESC
`, params)
.then(regions => res.send(regions))
.catch(e => next(e))
})
router.get('/:name', (req, res, next) => {
const params = {
name: req.params ? req.params.name : null
}
return req.neo4j.read(`
MATCH (region:Region { name: $name }) return region
`, params)
.then(regions => res.send(regions))
.catch(e => next(e))
})
module.exports = router;
From a browser, if I enter localhost:3000/regions I receive the list of all the Regions in Descending order.
But if I try to enter localhost:3000/regions/1 I receive nothing. The only difference between the two calls should be the order of the received data. The same for localhost:3000/regions/Lazio
It looks like it is not able to recognize patterns in the provided URL
The other really strange behavior is that if I set a breakpoint on any line of the file, the debugger doesn't stop. It looks like it is running another program ....
Can someone help?
Your first route needs to include the name parameter. Express routes aren't inclusive of any others defined elsewhere, so you need to spell it out a bit.
router.get('/:name/1', (req, res, next) => {
I was trying to make a routes for each ID I using a forEach loop but It stay loading until timeout reaches, all expected values are in place, all good but the second route is not running, I was fighting it despretly until now. I made sure there is a problem.
server.js
const router = require('express').Router();
function isAuthorized(req, res, next) {
if (req.user) {
next();
}
else {
res.redirect('/login')
}
}
let myguild = [];
router.get(`*`, isAuthorized, (req, res) => {
res.status(200);
console.log("wow");
console.log(req.user.guilds.length)
req.user.guilds.forEach(guild => {
myguild.push(guild);
})
console.log("Finished");
myguild.forEach(guild => {
console.log('Started')
router.get(guild.id, (req, res) => { // here is the problem
console.log("uh")
res.send("HAMBURGER")
console.log(req, res, guild)
})
console.log("Outed")
})
});
module.exports = router;
output:
wow
23
Finished
Started
Outed
Started
Outed
Started
Outed
Star... 'there is more but this is enough'
It should behave and run within server/${guild.id} but got (failed) request
Any Ideas?
You might need to redesign the API to better fit what you're trying to accomplish. If you already know which guilds are available then you'd need to create those before the server is initialized.
Even if they come from a database or are dynamic, you can loop through the guild "options" and create endpoints then provide access to them only if the user is qualified.
const { guilds } = require('./config')
const guildHandler = (req, res) => {
// Assuming you're doing more here
res.send('Hamburger')
}
guilds.forEach(guild => router.get(`/guilds/${guildId}`, guildHandler)
Or if you are NOT doingg something different in the middleware for each guild then you could just have a single route for guild.
router.get('/guilds/:guildId, guildHandler)
Not really sure what you're trying to accomplish but checkout out the Express docs. They solve most use cases fairly easily.
https://expressjs.com/en/api.html#req
You never call res.end() from your outer res.get() handler, so the request never completes.
And, with respect, creating route handlers like that in a loop is a mistake. It will lead to real performance trouble when your app gets thousands of guilds.
You'll want to use just one route, with a named route parameter, something like this.
const createError = require('http-errors')
router.get(':guildid', isAuthorized, (req, res, next) => {
const guildid = req.params.guildid
if (req.user.guilds.includes(guild)) {
console.log("uh")
res.send("HAMBURGER").end()
console.log(req, res, guildid)
} else {
next(createError(404, guildId + ' not found'))
}
})
Thanks for everyone helped.
Inspired answer
Final Result:
server.js
router.get('/:guildid', isAuthorized, (req, res, next) => {
console.log('started')
const guildid = req.params.guildid
if (req.user.guilds.some(guild => guild.id === guildid)) {
console.log('uh')
res.send("HAMBURGER").end()
} else {
res.sendStatus(404);
}
})
So I'm creating an authentication route but failing after executing the middleware.
verifyToken.js
module.exports = function (req, res, next) {
const token = req.get('auth-token')
if (!token) return res.status(401).send('Access Denied!')
try {
const verified = jwt.verify(token, process.env.TOKEN_SECRET)
req.user = verified
console.log(req.user) // successfully logging
next()
} catch (err) {
res.setHeader('Content-Type', 'application/json');
res.status(403).send('Invalid Token')
}
}
user.controller.js
exports.currentUser = verifyToken, async (req, res) => { // after verify token throwing an error 404
console.log('HIT') // not logging
// return res.send(req.user)
}
user.route.js
const { currentUser } = require('../controllers/users');
router
.route('/currentuser')
.post(currentUser)
I tried your code and I couldn't log 'HIT' as well. I suggest the following, split the exports # exports.currentUser into
var verifyToken = require('./verifyToken.js')
var response = async (req, res) => {
console.log('HIT') // not logging
// return res.send(req.user)
}
module.exports.currentUser = {verifyToken, response}
Then re-write route.js like this to get it to work.
const { currentUser } = require('./controller.js');
router.get('/currentUser', currentUser.verifyToken, currentUser.response)
To utilize next(), I had to use router.get('/get', middleware, callback). I changed the codes so that I could test it. You will need to edit the codes according to your context!
what command I should write in ExpressJS file just so that exposes a single HTTP endpoint (/api/search?symbol=$symbol&period=$period)
Working
app.get('/api/search/', (req, res) => {
res.send(req.query)
})
Not working:
app.get('/api/search?symbol=$symbol&period=$period', (req, res) => {
res.send(req.query)
})
app.get('/api/search?symbol=$symbol&period=$period', (req, res) => {
res.send(req.query)
})
In place of this, you have to write below code
const note = require('../app/controllers/note.controller.js');
// Create a new API CALL
app.get('/comment/get', note.index); // In socket.controller.js i have function with the name of index
//note.controller.js file code
exports.index = (req, res) => {
var requestTime = moment().unix();
req.body = req.query;
console.log(req.body); // you will able to get all parameter of GET request in it.
}
Let me know if i need to explain more about
And for sample code of express for API you can view this...
https://github.com/pawansgi92/node-express-rest-api-sample
What I think you're looking for is this:
app.get('/api/search', (req, res) => {
let symbol = req.query.symbol
let period = req.query.period
})
So when you navigate to /api/search?symbol=foo&period=bar
req.query.symbol is "foo"
and req.query.period is "bar"
I have a bunch of controller functions that do exactly the same thing: call a service function in another file of the same name. For the sake of example, I'll provide just two functions, but imagine there are several of them.
const express = require('express');
const router = express.Router();
const userService = require('./user.service');
const authorize = require('_helpers/authorize');
// routes
router.post('/authenticate', authenticate);
router.post('/create', create);
// ...
// ( it goes on like this )
// ...
module.exports = router;
function authenticate(req, res, next) {
userService.authenticate(req.body)
.then(user => user ? res.json(user) : res.status(400).json({ message: 'Error.' }))
.catch(err => next(err));
}
function create(req, res, next) {
userService.create(req.body)
.then(user => user ? res.json(user) : res.status(400).json({ message: 'Error.' }))
.catch(err => next(err));
}
// ...
// ( it goes on like this )
Is there a way in Javascript to avoid such repetitive code? ( I'm not new to programming but I'm a newcomer to Javascript ). I was thinking about automating this code generation with vim macros but maybe there's some package or feature in the language that can make this code look less verbose, maybe some sort of metaprogramming.
Create two utility functions, like this
handleUser which takes a res object and returns another function that takes user. This will allow you to inject res easily
handleError which takes a next callback and return another function that takes err
const handleUser = res => user =>
user ? res.json(user) : res.status(400).json({ message: 'Error.' });
const handleError = next => err => next(err);
const authenticate = (req, res, next) =>
userService.authenticate(req.body)
.then(handleUser(res)).catch(handleError(next));
const create = (req, res, next) => userService.create(req.body)
.then(handleUser(res)).catch(handleError(next));