Cannot read property 'jwtoken' of undefined - mern

here I generate the token at backend in express
..............
router.post("/login",async(req,res)=>{
const {email,password}=req.body;
if(!email || !password){
return res.status(401).send({error:"please filled the data properly"});
}
try {
const loginUser=await User.findOne({email:email});
if(!loginUser){
return res.status(400).send({error:"not found"});
}
const isMatch = await bcrypt.compare(password,loginUser.password);
if(isMatch){
const token=await loginUser.generateToken();
res.cookie("jwtoken",token,{
expires:new Date(Date.now()+15000000),
httpOnly:true,
//secure:true //it is applicable when we use https method
})
console.log(token);
res.send({message:"login success"});
}else{
res.status(400).send({error:"please enter correct data"})
}
} catch (error) {
res.status(400).send(error)
}
})
the token is create when i login in brouser
here is the about page (react)
...................
const verifyPage=async()=>{
try{
const res=await fetch('/about',{
method:"GET",
headers:{
Accept:"application/json",
"Content-Type":"application/json"
},
credentials:"include"
});
const data=await res.json();
console.log(data);
if(!res.status===200){
const err=new Error(res.error);
throw err;
}
}catch(err) {
console.log(err);
history.push("/login");
}
}
useEffect(()=>{
verifyPage();
},[])
.............
here I verify the token
...........
router.get("/about",Authentication,(req,res)=>{
res.send(req.rootUser);
})
........
The authentication page
............
const jwt = require("jsonwebtoken")
const User=require("../models/shegma")
const Authentication=async (req,res,next)=>{
try{
const token=req.cookies.jwtoken;
console.log(token)
const verifyToken=jwt.verify(token,process.env.TOKENID);
console.log(verifyToken);
const rootUser=await User.findOne({_id:verifyToken._id,"tokens.token":token})
if(!rootUser){throw new Error("user not found")}
req.token=token;
req.rootUser=rootUser;
req.userID=rootUser._id;
next();
}catch(err){
res.status(401).send("no token found");
console.log(err);
}
}
module.exports=Authentication;
..........
here is the error
......
TypeError: Cannot read property 'jwtoken' of undefined
at Authentication (C:\Users\ASUS\Desktop\mern\server\middleware\Authentication.js:6:33)
at Layer.handle [as handle_request] (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\ASUS\Desktop\mern\server\node_modules\express\lib\router\index.js:47:12)

At first, you need to install cookie-parser inside your server folder
npm i cookie-parser
Then, require cookie-parser inisde that .js file where you have initialized express
const cookieParser = require('cookie-parser')
After this, below const app = express(); just write
app.use(cookieParser())
Here is the full code:-
const express = require('express');
const cookieParser = require('cookie-parser')
const app = express();
app.use(cookieParser())

Do you happen to be parsing the cookies on the incoming request anywhere in your express code?
The req.cookies object being undefined leads me to believe you may not be parsing the request for cookies or that the parsing is not happening before the Authentication handler is called.
For reference: express cookie-parser

Related

How to send a header to a MERN api

I am creating a MERN application and I have a problem, in the back end I have the protected routes through a function called verifytoken that looks for the token as a header, on the other hand, in the front I receive a token that I keep in the local storage, how can I send the local storage as a header when calling that API?
I attach my code
frontend function that receives the token and stores it in localstorage
`import axios from "axios";
const jwtString = 'jwtlibraryyt'
export const loginUser = async (userObj) => {
const response = await axios.post(`http://localhost:3001/login`, userObj);
const { user, token} = response.data;
const {_id, ...userStored} = user;
localStorage.setItem(jwtString, token );
return response;
}`
frontend function that tries to call the protected route and send the local storage as a header
`const Books=()=> {
const [books, setBooks] = useState([]);
useEffect(() => {
getBooks();
},[])
async function getBooks(){
if(!localStorage.getItem("jwtlibraryyt")){
}
else{
const response = await axios.get('http://localhost:3001/books',{ headers: { token:localStorage.getItem('jwtlibraryyt') }});
setBooks(response.data);
}
}`
protected backend path
`router.get('/books', UserController.verifyToken,BookController.allBooks)`
verifytoken function found in the backend
`UserMethods.verifyToken = async (req, res, next) => {
let token = req.headers["token"];
if (!token) return res.status(403).json({ message: "Dame un token" });
try {
const decoded = jwt.verify(token, SECRET='elbicho');
req.currentUserId = decoded._id;
const user = await Users.findById(req.currentUserId, { password: 0 });
if (!user) return res.status(404).json({ message: "No se encontro el usuario" });
next();
} catch (error) {
return res.status(401).json({ message: "Usted no tiene autorizacion" });
}
};`

HTML Script cannot get fetch data

I try to get my data from mongoDB then use res to send all content to client side but I keep getting undefined, can anyone help me? Thank yall!!!
//// server.js
app.get('/user/show', userController.userList);
//// controller
const usersList = async (req, res) => {
const users = await User.find({});
const usersStr = JSON.stringify(users);
// tried console.log(userStr), can get correct output
res.json({'users': usersStr});
}
//// HTML Script
async function test() {
const result = fetch('/user/show',{
method: 'GET',
headers: {
'Contect-Type': 'application/json',
}
}).then((response) => response.json());;
console.log(result.messages.);
}
test();
If the data of the client come undefined myabe you dont have body-parser install.
body-parser
npm i body-parser
your index.js
const bodyParser = require('body-parser')
// app by app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true })

message": "Webhook call failed. Error: UNAVAILABLE, State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500." in dialogflow fulfillment

I am trying to send email using dialogflow intents from my gmail. But it throws the same error every time and I am unable to understand the issue behind this. The same thing stand alone from my code is able to send emaail to various email addresses. So i guess the code works just fine . Please have a look at my code .
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const nodemailer = require("nodemailer");
const admin = require("firebase-admin");
const axios = require("axios");
admin.initializeApp({
credential:admin.credential.applicationDefault(),
databaseUrl:'ws://***************/'
});
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function emailSend(){
const email= agent.parameters.email;
const name= agent.parameters.name;
const subject= agent.parameters.subject;
const message = agent.parameters.message;
}
const nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: '*****#gmail.com',
pass: '***********'
}
});
var mailOptions = {
from: 'Mamuni',
to: 'email' ,
subject: 'subject' ,
text: 'message'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
let intentMap = new Map();
intentMap.set('emailSend',emailSend);
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
agent.handleRequest(intentMap);
});
The error probably is indicative that your code is not reachable or probably not being served via a HTTPS endpoint. I suggest the following:
Is the code available over a publicly accessible endpoint?
If the above is yes, is it being served over a secure channel i.e. HTTPS?

encoding decoding Json using RSA Angular and Express.js

I have a frontend Angular.ts and a backend Express.js. I am decrypting user credentials in the frontend using RSA and sending all the data as an encrypted string to the backend.
When I try to catch the data in the backend to decrypt it, it reads the received object as [object Object] which makes it impossible to decrypt. This is the code =>:
FRONTEND httpService.ts:
sendmail(user: { name: any; email: any; host: any }) {
console.log(user);
const encJsonUser = this.rsaHelper.encryptWithPublicKey(
JSON.stringify(user)
);
console.log(encJsonUser);
return this.http.post(environment.apiUrl + '/sendemail', encJsonUser);
}
BACKENDemail.js:
router.post('/', async (req, res) => {
let path = null;
const encryptedData = req.body;
console.log("RECEIVED ENCRYPTED BODY: " + encryptedData);
const privateKey = fs.readFileSync("privateKey.key.pem", "utf8");
console.log("toDecryptData::: " + encryptedData);
const decryptedData = decryptedDataFromAngular(encryptedData, privateKey);
console.log("DECRYPTED-DATA: " + decryptedData);
axios.post("http://localhost:8080/pdf", {host: encryptedData.host}).then(async function (response) {
path = response.data.scan_id;
}).then(() => {
emailPdfGenerator(encryptedData);
});
})
function decryptedDataFromAngular(encryptedData, privateKey) {
// encryptedData = Buffer.from(encryptedData, "base64");
const body = JSON.parse(encryptedData);
// console.log("ENCRYPTED DATA 2222:::: " + encryptedData);
console.log("ENCRYPTED DATA 2222:::: " + body);
const decryptedData = crypto.privateDecrypt(
{
key: privateKey,
// In order to decrypt the data, we need to specify the
// same hashing function and padding scheme that we used to
// encrypt the data in the previous step
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
},
body
);
console.log("decrypted data: ", decryptedData.toString());
console.log("DE RAW DATA" + decryptedData);
return decryptedData;
}
error message:
RECEIVED ENCRYPTED BODY: [object Object] toDecryptData::: [object Object] undefined:1 [object Object] ^
SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse ()
at decryptedDataFromAngular (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\routes\email.js:60:23)
at C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\routes\email.js:31:27
at Layer.handle [as handle_request] (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\route.js:144:13)
at Route.dispatch (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\route.js:114:3)
at Layer.handle [as handle_request] (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\index.js:284:15
at Function.process_params (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\index.js:346:12)
at next (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\index.js:280:10)
[nodemon] app crashed - waiting for file changes before starting...
I stopped using crypto, and I am using forge to solve the problem because crypto just didn't help me.
This is my code:
async function decryptUser(encryptedUserData) {
const name = await decryptString(encryptedUserData.name);
const email = await decryptString(encryptedUserData.email);
const host = await decryptString(encryptedUserData.host);
const decryptedUser = {
name: name,
email: email,
host: host,
}
return decryptedUser
}
async function decryptString(encryptedString) {
const rsa = forge.pki.privateKeyFromPem(PRIVATE_KEY);
return await rsa.decrypt(encryptedString);
}

Access Body Param NodeJS Express

I have a route
router.post('/api/getSessionTimeOut', apiController.getSessionTimeOut);
This is in my controller
function getSessionTimeOut(req, res) {
res.send(req.body.session); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
var options =
{
method: 'POST',
url: 'http://api/json',
body:
{
id: 1,
method: 'get',
params: [
{
url: '/cli/global/system/admin/setting'
}
],
session: req.params.session
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body, response);
res.send(response.result);
});
};
After making a POST to the route with session as body via Postman
I kept getting
Red alert! Red alert!: TypeError: Cannot read property 'session' of undefined
at getSessionTimeOut (/Users/doe/Desktop/express-app/controllers/api.js:50:23) at Layer.handle [as handle_request] (/Users/doe/Desktop/express-app/node_modules/express/lib/router/layer.js:95:5) at next (/Users/doe/Desktop/express-app/node_modules/express/lib/router/route.js:137:13) at Route.dispatch (/Users/doe/Desktop/express-app/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/Users/doe/Desktop/express-app/node_modules/express/lib/router/layer.js:95:5) at /Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:281:22 at Function.process_params (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:335:12) at next (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:275:10) at Function.handle (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:174:3) at router (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:47:12) at Layer.handle [as handle_request] (/Users/doe/Desktop/express-app/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:317:13) at /Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:284:7 at Function.process_params (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:335:12) at next (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:275:10) at serveStatic (/Users/doe/Desktop/express-app/node_modules/serve-static/index.js:75:16) at Layer.handle [as handle_request] (/Users/doe/Desktop/express-app/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:317:13) at /Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:284:7 at Function.process_params (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:335:12) at next (/Users/doe/Desktop/express-app/node_modules/express/lib/router/index.js:275:10) at expressInit (/Users/doe/Desktop/express-app/node_modules/express/lib/middleware/init.js:40:5)
index.js
import express from 'express'
import favicon from 'serve-favicon'
import path from 'path'
import bodyParser from 'body-parser'
// Controllers
import apiController from './controllers/api'
const router = express.Router();
const app = express();
const PORT = 3000;
//For public folder
app.use(express.static('public'))
app.use(router)
app.use('/images',express.static('images'))
app.use(favicon(path.join(__dirname,'public','favicon.ico')))
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
router.get('/', (req,res) => {
res.send('Welcome to the backend provisioning daemon to program FortiManager')
});
// app.use( express.json());
app.use(express.urlencoded({extended: true}))
app.set('trust proxy', 'loopback');
//Fortinet
router.post('/api/getSessionTimeOut', apiController.getSessionTimeOut);
router.post('/api/login', apiController.login);
//Error handling function
app.use((err,req,res,next) => {
console.error(err.stack)
res.status(500).send(`Red alert! Red alert!: ${err.stack}`)
});
// app listen
app.listen(PORT, () => {
console.log(`Your server is running on ${PORT}`)
}
);
Try moving
app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true }));
right after
const app = express();
Why, because you need to use/register middlewares on your server/app before registering any route on your server. This will make sure that every request coming to the registered route is first passed through body-parsers and will let the body-parsers to do the construct the request data in its specified data structure or format.
Hope that helps
Thanks