My code:
module.exports = async (req, res, next) => {
const redirectURL = ((req.originalUrl.includes("login") || req.originalUrl === "/") ? "/selector" : req.originalUrl);
if(req.session.user){
return next();
} else {
const state = Math.random().toString(36).substring(5);
req.client.states[state] = redirectURL;
return res.redirect(`/api/login?state=${state}`);
}
};
Give me this error:
Cannot set properties of undefined (setting 'yhgrz0jg')
Can anyone help me I've tried everything and I can't solve it?
req.client.states is undefined, that's why you're getting error. Why are you setting it anyway, since you're not using that value anywhere later on?
Related
Hello Im getting error: Cannot read properties of undefined (reading 'split').
When I see it in the console
If I click the link to the error it shows me the browser.umd.js file with this line:
any one knows whats the problem?
code:
const verifyJwt = (req,res,next) => {
console.log('entered middle');
let name = 'token=';
const header = req.headers['cookie'];
const token = header && header.split('=')[1];
if (!token) return res.status(401).send({msg: "Login first please!"})
jwt.verify(token, process.env.TOKEN_KEY, (err, user) => {
if(err) return res.status(403).send({msg:"Not authoraized"})
next();
});
}
module.exports = verifyJwt
The problem occurs because of an other error that was found in the code but havent notice, because of this the string was undefined value and does not have the func split.
This is my middleware,
export const parseUser = (req, res, next) => {
const token_header = req.header('Authorization');
if (token_header) {
req.user = jwt_decode(token_header.split(' ')[1].split(' ')[0]);
req.token = token_header.split(' ')[1].split(' ')[0];
next();
} else {
next();
}
};
this is my router,
router.get('/get/', parseUser, swaggerValidation.validate,
async(req, res) => {
...
} catch (err){
...
}
});
i am trying to mock the parseUser function and assign req.user and req.token values using jest and pass it, i need those values to authorize user and need the value assigned to do database query, I am using jest to mock the functions, I have tried google and stackoverflow, i was not able to solve it with those example, i have tried below methods and others,
jest.mock('../../utils/permission');
const mockedParseUser = jest.mocked(parseUser, true)
mockedParseUser.mockReturnValueOnce({req.user: "value", req.token: "value");
i have also tried,
const return = {req.user: "value", req.token: "value"}
const mockedReturn = jest.fn((): any => return}
jest.spyOn('../../utils/permission', parseUser).mockImpementation((): any => mockReturn())
Nothing worked for me, can someone help me with mocking the parseUser().
I am new to nodejs and typescript and I want to add a new parameter in req.body say req.body.jwt_token.
I am using a middleware to update the request data model. The issue is that i am able to access (console.log works) the new key req.body.jwt_token just work in that function and is not accessible(don't even exist) apart from that.
I want to use req.body.jwt_token in some controller.
export function httpsProtocol(req: Request, res: Response, next: NextFunction) {
try {
if (req.headers.authorization != undefined) {
let authorization = req.headers.authorization;
let authorizationArr: string[] = authorization.split('Bearer')
if (authorizationArr[1] != undefined) {
let jwtToken = "Bearer " + authorizationArr[1].trim();
req.headers.Authorization = jwtToken;
req.body.jwt_token = authorizationArr[1].trim();
console.log(req.body.jwt_token); //able to console this
}
}
} catch (error) {
return res.status(422).json({
message: "something goes wrong",
error: error
});
}
next();
};
Please suggest the solution for this problem. how can i achieve this in nodejs and typescript. I am using express as framework
Thank You
💡 The only reason why you can not access req.body.jwt_token in your controller is that before you set the value, you next().
👨🏽🏫 Make sure to add your next() inside if/else condition. So, you can copy this code below 👇 and use it:
export function httpsProtocol(req: Request, res: Response, next: NextFunction) {
try {
if (req.headers.authorization != undefined) {
let authorization = req.headers.authorization;
let authorizationArr: string[] = authorization.split('Bearer')
if (authorizationArr[1] != undefined) {
let jwtToken = "Bearer " + authorizationArr[1].trim();
req.headers.Authorization = jwtToken;
req.body.jwt_token = authorizationArr[1].trim();
console.log(req.body.jwt_token); //able to console this
// your next here
next();
} else {
next(); // next or do some stuff
}
} else {
next(); // next or do some stuff
}
} catch (error) {
return res.status(422).json({
message: "something goes wrong",
error: error
});
}
// next(); your next here only make your req.body.jwt_token is undefined
};
Maybe this answer will help you to know the reason: passing value from middleware to controller in restify using req.data is not working?
I hope it can help you 🙏.
Good day,
I was surprised that I couldn't find any information on the getRequestHandler and render functions of the next package.
I am trying to set up a custom server and was wondering what the render function was actually doing or why it is even used? getRequestHandler clearly renders the app so why would I ever want to use render to pass in a path manually? Also, what is the point of passing in pathname and query separately?
I am clearly confused regarding the use cases of these two - in which situation would I use one or the other?
Thank you for everyone's help.
Anagni
See https://nextjs.org/docs/advanced-features/custom-server
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') {
app.render(req, res, '/b', query)
} else if (pathname === '/b') {
app.render(req, res, '/a', query)
} else {
handle(req, res, parsedUrl)
}
}).listen(3000, err => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
getRequestHandler vs render
app.getRequestHandler returns a request handler which we can use to parse all HTTP requests. app.render checks if static assets need to serve. It also checks if the page requested is a blocked/internal page. After those checks pass, Next.js also use the same request handler that we will get from app.getRequestHandler. If we use request handler directly, we won't get those checks and run into issues which we need to handle it manually.
Here are parts of the source code that deal with custom server. I hope it make the answer a bit more clear.
// next/next-server/server/next-server.ts
// This function expose a private method, which used by render
public getRequestHandler() {
return this.handleRequest.bind(this)
}
// render method
public async render() {
// .... more code
// check if server needs to handle static files
if (
!query._nextDataReq &&
(url.match(/^\/_next\//) ||
(this.hasStaticDir && url.match(/^\/static\//)))
) {
return this.handleRequest(req, res, parsedUrl)
}
// check the requested page is a internal/blocked page
if (isBlockedPage(pathname)) {
return this.render404(req, res, parsedUrl)
}
const html = await this.renderToHTML(req, res, pathname, query)
// Request was ended by the user
if (html === null) {
return
}
// respond with rendered HTML
return this.sendHTML(req, res, html)
}
Path & Query
I think Next.js query is a bit different from URL query strings. You can have a route like this '/a' and pass in a query object without adding those query to your URL.
This is my best effort to answer the question. Hopefully, I can provide some help.
Reference:
https://github.com/vercel/next.js/blob/canary/packages/next/next-server/server/next-server.ts
I'd like to remove an object element from my user object, I'm using pull to remove it, but it returns
TypeError: user.company.pull is not a function
router.put('/reset', passport.authenticate('jwt', {session:false}), (req, res, next)=> {
user = req.user;
var id_student = user.id;
var id_company = user.company;
var results = [];
User.findById(id_student, function(err, user) {
if(err) {
console.log(err);
return res.status(500).send({message: "Error"});
}
if(!user) {
return res.status(404).send({message: "User Not Found"});
}
user.company.pull({'company': id_company});
res.send(user);
});
});
Effectively, user.company.pull is probably undefined, rather than the function that you're looking for.
If user.company doesn't exist, then user.company is going to be undefined, and there's not a pull method defined on undefined. This means that you're effectively trying to call undefined.pull({'company': whatever}), which will never work.
Try adding a guard to ensure that you have a company attached to a user, in the same way you check to ensure that the user exists. For example:
if (!user.company) {
return res.status(404).send({ message: 'Company not found'});
}
Use 'use strict'; at top of js files.
Read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode for more information
Check if variable user has property copmany or not and handle it.
Use this condition
if(!user || !user.hasOwnProperty('company')) {
return res.status(404).send({message: "User Not Found"});
}