req.user is unidentified in session (Node, express, session, passport) Ask Question

For some reason req.user is undefined, and after 4+ hours of trying to figure out why, I’m asking here. I even copy-pasted the server/index.js file of a friend’s server, changed the auth strategy so it worked for mine, and I get the same issue.

Everything else is working. It redirects to auth0, comes back to the correct place, either creates a new user in the DB or finds the user. In passport.serializeUser it has all the data I passed along. But when I hit the ‘/auth/me’ endpoint, req.user is undefined.

server/index.js

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors')
const session = require("express-session");
const passport = require('passport');
const Auth0Strategy = require('passport-auth0');
const massive = require('massive');
const axios = require('axios');
const process = require("process");
const moment = require('moment');

const app = express();

//app.use(express.static(__dirname + './../build'));
app.use(bodyParser.json());
app.use(cors());

app.use(session({
    secret: process.env.SECRET, 
    cookie: { maxAge: 60000 },
    resave: false,
    saveUninitialized: true
   }));
app.use(passport.initialize());
app.use(passport.session()); 

// Use the session middleware
massive(process.env.CONNECTION_STRING)
.then( (db) => {
    console.log('Connected to Heroku')
    app.set('db', db);
}).catch(err=>console.log(err))
 


passport.use(new Auth0Strategy({
    domain: process.env.AUTH_DOMAIN,
    clientID: process.env.AUTH_CLIENT_ID,
    clientSecret: process.env.AUTH_CLIENT_SECRET,
    callbackURL: process.env.AUTH_CALLBACK
}, (accessToken, refreshToken, extraParams, profile, done) => {
    const db = app.get("db");
    const userData = profile._json;

    db.find_user([userData.identities[0].user_id]).then(user => {
    if (user[0]) {
        return done(null, user[0]);
    } else {
        db.create_user([
            userData.given_name,
            userData.family_name,
            userData.email,
            userData.identities[0].user_id
        ])
        .then(user => {
            return done(null, user);
        });
    }
    });
}))

passport.serializeUser( (user, done) => {
    //console.log('serializeuser', user)
    done(null, user);
}) 

passport.deserializeUser( (id, done) => {
    app.get("db").find_session_user([id])
        .then(user => {
        console.log(user);
        done(null, user[0]);
        });
})

app.get('/auth', passport.authenticate('auth0'));
app.get('/auth/callback', passport.authenticate('auth0', {
    successRedirect: process.env.SUCCESS_REDIRECT
}))

app.get('/auth/me', (req, res) => {
    console.log('auth/me endpoint hit')
    console.log(req.user)
    if(!req.user){
        return res.status(401).send('No user logged in.');
    }
    return res.status(200).send(req.user);
})

app.listen(process.env.PORT, () => console.log(`Listening on port: ${process.env.PORT}`));

Write file to directory then zip directory Ask Question

I am trying to write a file to a directory templates then stream a zip with the content that was written. However, the when the zip file is returned it says Failed - Network Error which is due to the fs.writeFile in the controller. If i remove the WriteFile stream then the zipping works fine. My question is how do i first write the file then run the zip. There seems to be something synchronous happening with the archiving and file writing of typeArrayString.

Controller:

exports.download_one_feed = function(req, res, next) {
  Feed.findOne({'name': req.params.id})
  .exec(function(err, dbfeeds){
    if(err){
      res.send('get error has occured in routes/feeds.js');
    } else {
      const feedArray = dbfeeds.feed.data;

      // write file
      // get from db collection & write file to download
      const typeArrayString = JSON.stringify(feedArray);

      let type = 'b'; // test only

      fs.writeFile(path.join(appDir, 'templates/' + type + '/template.json'), typeArrayString, (err) => {
        if (err) throw err;
        console.log('Saved!');
      })
      archiverService.FileArchiver(feedArray, res);
    }
  })
};

Archive Service

const archiver = require('archiver')
const zip = archiver('zip')
const path = require('path')
const fs = require('fs')
const appDir = path.dirname(require.main.filename)

exports.FileArchiver = function (feedArray, res) {
    // const app = this.app;
    const uploadsDir = path.join(appDir, '/uploads/');
    const templatesDir = path.join(appDir, '/templates/');
    const extensions = [".jpg", ".png", ".svg"];
    let imageArray = [];

    const feedArrayObject = JSON.parse(feedArrayString);

    feedArrayObject.forEach(function(x){iterate(x)}); // grab image names from object
    imageArray = uniq_fast(imageArray); // remove duplicates

    // zip images
    for (let i = 0; i < imageArray.length; i++) {
      console.log(imageArray[i])
      const filePath = path.join(uploadsDir, imageArray[i]);
      zip.append(fs.createReadStream(filePath), { name: 'images/'+imageArray[i] });
    }

    res.attachment('download.zip');
    zip.pipe(res);
    // zip template directory
    console.log(templatesDir)
    zip.directory(templatesDir, false);
    zip.on('error', (err) => { throw err; });

    zip.finalize();

    return this;
  }

Getting invalid JSON on API call Ask Question

I’m trying to use GoToMeeting’s API and making a POST request to create a meeting. At the moment, I’m just trying to hardcode the body of the meeting and send headers but I’m receiving and I’m invalid JSON error and not sure why. Here’s the code for that route:

app.post('/new-meeting', (req, res) => {

  const headers = {
    'Content-Type': 'application/json',
    Accept: 'application / json',
    Authorization: 'OAuth oauth_token=' + originalToken
  };

  console.log('-----------------------------------------------------------')
  console.log('Acess Token:');
  console.log('OAuth oauth_token=' + originalToken);
  console.log('-----------------------------------------------------------')

  const meetingBody = {
    subject: 'string',
    starttime: '2018-03-20T08:15:30-05:00',
    endtime: '2018-03-20T09:15:30-05:00',
    passwordrequired: true,
    conferencecallinfo: 'string',
    timezonekey: 'string',
    meetingtype: 'immediate'
  };

  return fetch('https://api.getgo.com/G2M/rest/meetings', {
    method: 'POST',
    body: meetingBody,
    headers: headers
  }).then(response => {

    console.log('response:');
    console.log(response);


    response
      .json()
      .then(json => {
        res.send(json);
        console.log(req.headers);
      })
      .catch(err => {
        console.log(err);
      });
  });
});

When I hit that router, I get the following error:

{
  "error": {
    "resource": "/rest/meetings",
    "message": "invalid json"
  }
}

Any advice would be appreciated!

Access req.user to save id to mongoDB Ask Question

I’m currently having an issue with figuring out how I can access req.user so I can get the logged in users id and save it with the items that they save on the web page. That way when they load the web page they only get their items. The only place I know where I have access to req.user is in my /router/auth.js file. I want to figure out a way to access it in a different router file.

router/auth.js

const express = require('express');
const passport = require('passport');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');

const config = require('../config');

const router = express.Router();

const createAuthToken = function (user) {
  return jwt.sign({ user }, config.JWT_SECRET, {
    subject: user.username,
    expiresIn: config.JWT_EXPIRY,
    algorithm: 'HS256'
  });
};

const localAuth = passport.authenticate('local', { session: false });
router.use(bodyParser.json());

router.post('/login', localAuth, (req, res) => {
  const authToken = createAuthToken(req.user.serialize());
  res.json({ authToken });
});

const jwtAuth = passport.authenticate('jwt', { session: false });

router.post('/refresh', jwtAuth, (req, res) => {
  const authToken = createAuthToken(req.user);
  res.json({ authToken });
});

/router/portfolio.js

router.post('/:id', (req, res) => {
  const id = req.params.id;
  const { holdings } = req.body;

  CryptoPortfolio.findOne({ id }, (err, existingCoin) => {
    if (existingCoin === null) {
      getCoins(id)
        .then(x => x[0])
        .then(value =>
          CryptoPortfolio.create({
            id: value.id,
            holdings,
            _creator: this is where I want to add req.user.id
              }).then(() => value))
        .then(newItem => {
          res.status(201).json(newItem);
        })
        .catch(err => {
          console.error(err);
          res.status(500).json({ message: 'Internal server error' });
        });
    } else {
      const capitalizedId = id.charAt(0).toUpperCase() + id.slice(1);
      res.json(`${capitalizedId} already in watchlist`);
    }
  });
});

TypeError: Cannot read property 'length' of undefined nodejs Ask Question

Everything runs properly from nodemon until I go to the browser to register and got the error message “TypeError: Cannot read property ‘length’ of undefined”
When I decided to comment the if(“req.body.password.length > 4) the registration didn’t work complaining password didn’t match.
Please help am very new to Node

https://gist.github.com/dngoyb/de020c2686a1104af748593d37e0e082

this is the full error

TypeError: Cannot read property 'length' of undefined
    at router.post (/home/zidiou/Documents/Vidjot/Vidjot/routes/users.js:26:28)
    at Layer.handle [as handle_request] (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/layer.js:95:5)
    at /home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:335:12)
    at next (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:174:3)
    at router (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:317:13)
    at /home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:335:12)
    at next (/home/zidiou/Documents/Vidjot/Vidjot/node_modules/express/lib/router/index.js:275:10)
    at /home/zidiou/Documents/Vidjot/Vidjot/app.js:59:4

Why content-type in header remains text/plain though I set it as application/json Ask Question

I use fetch() to post json data as below

var data = {
            name: this.state.name,
            password: this.state.password
        }
fetch('http://localhost:3001/register/paitent', {
            method: 'POST',
            body: JSON.stringify(data), 
            mode: 'no-cors',
            headers: new Headers({
                'Content-Type': 'application/json'
            })
        })
        .then(res => res.json())

I always get {} in request.body in my express server router, and I figure out the problem is in sending request, it’s always ‘text/plain’. Why this happens?

enter image description here

How to check if array includes string in PUG template Ask Question

I am using NodeJS with Express and the PUG view engine.

I am attempting to check if an array contains a certain string. I have tried the builtin javascript methods such as:

array.includes(str)
array.indexOf(str) > -1.

However neither of these options seem to work. How can I check if an array contains a certain string in PUG?

if example_array.length > 0
  span() Array contains elements! // This works and appears on page
  if example_array.includes('example string') // This does not work
    span() Array includes example string! // This does not appear on page

Cannot read property 'query' of undefined in Node & Postgresql Ask Question

const pool = new pg.Pool(config);
var tablename = req.body.tablename;

pool.connect(function (err, client, done) {
    var query_get_value = 'SELECT * FROM '+ tablename;
    client.query(query_get_value, function (err, result) {
        done();
        if (err) {
                throw err;
        }
        var rows = result.rows;
.....

this code runs correctly for a while, but a few seconds later, I received following errors:(I call this function repeatedly on the view side using setInterval function)

 client.query(query_get_value, function (err, result) {
                   ^

TypeError: Cannot read property 'query' of undefined
    at /var/node_project/controllers/index.js:630:10
    at client.connect (/var/node_project/node_modules/pg-pool/index.js:219:9)
    at Connection.connectingErrorHandler (/var/node_project/node_modules/pg/lib/client.js:123:14)
    at Connection.emit (events.js:127:13)
    at Socket.<anonymous> (/var/node_project/node_modules/pg/lib/connection.js:117:12)
    at Socket.emit (events.js:127:13)
    at addChunk (_stream_readable.js:269:12)
    at readableAddChunk (_stream_readable.js:256:11)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onread (net.js:598:20)

Simple incrementer in Express MongoDB does not return an error when it should Ask Question

I am simply trying to create a post request where a variable name is passed in with the request and it is either created and stored in the database or incremented if it already exists.

Should be simple but I am afraid I am using update incorrectly or something because I am getting weird behavior:

app.post('/increment', function(req, res) {
    const params = req.body;
    const imcrement = verifyIncrement(params);
    if (imcrement != false) {
        //Insert it in if we already have it
        var id = imcrement.variable;
        console.log(id);
        db.collection(collection_counter).update({variable: id}, { $inc: {visit_count: 1}}, (err, data) => {
            if (!err) {
              console.log("No error we incremented");
              res.send({err: false, message: data.visit_count});
            } else {
                console.log("We want to insert new");
                db.collection(collection_counter).insert({variable: id, visit_count: 1}, (err, data) => {
                    if (err) {
                        console.log("We didnt");
                        res.send({err: false, message: "Error"})
                    } else {
                        console.log("We did");
                        res.send({err: false, message: data.visit_count})
                    }
                });
            }
        })
    } else {
        res.send({err: true, message: "Invalid data in"})
    }
})

For whatever reason no matter what I pass in for a variable name it always goes to the “No error we incremented” block despite the fact that a variable with id does not exist in the database.

In fact when I get the json response it just has err: false and the message part does not come through. What is going on here?

Node express-session not returning myvar(or not using the same sessionID) Ask Question

When trying out express-session, I couldn’t retrieve anything from my previous entries when I stored a variable to a session. Not only that, my session ID has changed. Why is this?

Here is my server.js:

const express = require('express')
const session = require('express-session')
const bodyParser = require('body-parser')

const app = express()

app.use(express.static(__dirname + "/src"))
app.use(bodyParser.json())
app.use(session({secret: 'tester', saveUninitialized: true, resave: false, cookie: {maxAge: 5*60000}}))


app.get("/",(request, response) => {
    response.sendFile(__dirname + "/front_end.html")
    //response.end('This is a test for stuff')
})

app.post("/resources", (request, response)=>{
    request.session.myvar = "Hello Person"
    console.log(request.session.myvar);
    console.log(request.sessionID)
    response.json({message: "Success", url: "/respond"})
})

app.get("/respond", (request, response)=>{
    console.log(request.session.myvar)
    console.log(request.sessionID)
    response.send('stuff')
})

app.listen(3000, (err) => {
    if (err) {
        console.log('Server is down');
        return false;
    }
    console.log('Server is up');
})

Here is the front end html:

<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <button id="test">Test</button>
        <script src="/front_end.js"></script>
    </body>
</html>

And this is my front end js:

document.getElementById("test").addEventListener("click", () => {
    fetch('/resources', {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            "name": "Test",
            "pass": "Tester"  //ignore the fact that this actually doesn't do anything yet.
        })
    }).then((response) => {
    return response.json()
    }).then((json)=>{
        window.location.assign(json.url)
    });
});

Here is the result from the command line(server end):

Server is up
Hello Person
DQH0s5Mqu9FasN5It49xD1ZAtkCbj0P5
undefined
p5_imn5FXxxO-i2lR62TNGXEd-o2WHGP