Advanced Node Challenge problem: How to Put a Profile Together

I can’t pass the only test on this challenge:

Correctly added a Pug render variable to /profile

Test output:

You should be passing the variable username with req.user.username into the render function of the profile page

The code:

'use strict';

const express     = require('express');
const bodyParser  = require('body-parser');
const fccTesting  = require('./freeCodeCamp/fcctesting.js');
const passport = require('passport');
const session = require('express-session');
const mongo = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID;
const LocalStrategy = require('passport-local');
//const pug = require('pug');

const app = express();

fccTesting(app); //For FCC testing purposes
app.use('/public', express.static(process.cwd() + '/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: true,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

app.set("view engine", "pug");

//Database connect
mongo.connect(process.env.DATABASE, (err, db) => {
  if(err){
    console.log(`Database error: ${err}`);
  } else {
    console.log("Succesful database connection");
    
    passport.serializeUser((user, done) => {
      done(null, user._id);
    });
    
    passport.deserializeUser((id, done) => {
      db.collection("users").findOne({
        _id: new ObjectID(id)
      }, (err, doc) => {
        done(null, doc);
      });
    });
    
    passport.use(new LocalStrategy((username, password, done) => {
      db.collection("users").findOne({
        username: username
      }, (err, user) => {
        console.log(`User ${username} attempted to log in.`);
        if(err){
          done(err);
        }
        if(!user){
          done(null, false);
        }
        if(password !== user.password){
          done(null, false);
        }
        done(null, user);
      });
    }));
    
    app.route('/')
      .get((req, res) => {
      res.render(process.cwd() + '/views/pug/index.pug', {title: "Home Page", message: "Please login", showLogin: true});
    });
    
    app.listen(process.env.PORT || 3000, () => {
      console.log("Listening on port " + process.env.PORT);
    });
    
    app.route("/login").post(passport.authenticate("local", { failureRedirect: "/" }), (req, res) => {
      res.redirect("/profile");
      console.log(`User ${req.user} attempted to log in.`);
    });
    
    const ensureAuthenticated = (req, res, next) => {
      if(req.isAuthenticated()){
        next();
      }
      res.redirect("/");
    }
    
    app.route("/profile")
      .get(ensureAuthenticated, (req, res) => {
      res.render(process.cwd() + "views/pug/profile.pug", { username: req.user.username });
    });
    
  }
});

Challenge link:
How to Put a Profile Together

2 Likes

Do you have completed the other points?

Go ahead and pass the object containing the variable username equaling ‘req.user.username’ into the render method of the profile view.

:+1:

Then go to your ‘profile.pug’ view and add the line h2.center#welcome Welcome, #{username}!

?

Also in the profile, add a link to /logout . That route will host the logic to unauthenticate a user. a(href='/logout') Logout

?

1 Like

Hey, thanks for your response :smile:.

views/pug/profile.pug:

html
  head
    title FCC Advanced Node and Express
    meta(name='description', content='Profile')
    link#favicon(rel='icon', href='https://hyperdev.com/favicon-app.ico', type='image/x-icon')
    meta(charset='utf-8')
    meta(http-equiv='X-UA-Compatible', content='IE=edge')
    meta(name='viewport', content='width=device-width, initial-scale=1')
    link(rel='stylesheet', href='/public/style.css')
  body
    h1.border.center FCC Advanced Node and Express
    //add your code below, make sure its indented at this level
    h2.center#welcome Welcome, #{username}!
    a(href='/logout') Logout
    
    
    script(src='https://code.jquery.com/jquery-2.2.1.min.js', integrity='sha256-gvQgAFzTH6trSrAWoH1iPo9Xc96QxSZ3feW6kem+O00=', crossorigin='anonymous')
    script(src='/public/client.js')

And the dependencies:

  "dependencies": {
    "express": "^4.14.1",
    "cors": "^2.8.1",
    "body-parser": "^1.16.0",
    "mongodb": "^2.2.22",
    "helmet": "^3.4.0",
    "pug": "^2.0.3",
    "passport": "^0.4.0",
    "express-session": "^1.16.1",
    "passport-local": "^1.0.0"
  },

Link to the project

Thanks a lot for any assistance or advice you might give!

Uhm, do you have a connection string or something? This is what i see when i open the console:

Basically it complains because the .env file is not filled with the correct properties. If you cannot connect to mongo you cannot connect to the database, and all of your routes and passport stuff are inside the callback of the connection ^^
I tried to move them out just to see something in the split screen: actually i can see the form but when i try to submit the values it crashes obviously ( there is no connection string or similar ^^ )

I think you missed this challenge ( implement the serialization of a passport user ) or at least this part:

You can now uncomment the block in deserializeUser and remove your done(null, null) . Be sure to set DATABASE in your .env file to your database’s connection string (for example: DATABASE=mongodb://admin:pass@mlab.com:12345/my-project ). You can set up a free database on mLab. Congratulations- you’ve finished setting up serialization!

Basically you have to:

  • create an account ( for free) on Atlas ( Mongodb Atlas - home );
  • create a new cluster;
  • clck the button ‘connect’: this will open a modal where you can see the connection string you can use to connect your app ( not from shell or compass).
  • back to your glitch project, add your connection string to the .env file as the DATABASE value and fill out the other values too ( SECRET and SESSION_SECRET are just random strings, MADE_WITH …i have no idea :stuck_out_tongue: ). Remember that in the .env file string can be written as is, it does not need quotation marks^^

Good luck and have fun! :grinning:

Hey! Once again, thanks a lot for your help.
The connection string is there, but it isn’t shown for non-members. I assumed that only meant that everything under .env would be hidden, but based on what you’re saying seems it cannot be accessed either. :upside_down_face:

1 Like

Ah my bad, didn’t knew that^^ You can hide it again for security reason, i can replace it with another one for testing purpose ^^
I can’t say what’s wrong at the moment :frowning: , will look into it tomorrow morning!

1 Like

Uhm…
I did some testing: after quite a bit i got that the app doesn’t save the user it retrieves in the cookie session (so when it redirects it lose the req.user), dunno if that is because i am not registered (thus the project is not saved) or about other reasons^^

Anyway that’s not the point: the only thing i can suggest to you is to add the initial forward slash and remove some spaces, something like this:
'/views/pug/profile', {username:req.user.username}
It doesn’t work for me but i encountered some loading problem on glitch so…crossed fingers! :crossed_fingers:

5 Likes

You are a lifesaver! The initial forward slash did the trick. Thanks a lot!

1 Like

The tests are again getting in the way of using better coding techniques. Spent about fifteen minutes debugging this one.

My original code:

const PUG_DIR = process.cwd() + '/views/pug/';
...
app.get('/profile', ensureAuthenticated,
  (req, res) => res.render(
    PUG_DIR + 'profile.pug',
    { username: req.user && req.user.username }
));

The code that passed the test:

 app.get(
  '/profile',
  ensureAuthenticated,
  (req, res) => res.render(
    process.cwd() + '/views/pug/profile.pug',
    { username: req.user.username }
));

The original code was working perfectly and adhered to decent coding practices, but to pass the test, I could not use a constant for the pug directory, and I could not use a check to make sure that user was defined.

1 Like

The tests definitely need to be improved.

Welcome, jaywalker.

This whole section is currently under QA, but if you have any suggestions, you can head over to the GitHub repo, or #contributors subforum, and make a suggestion or contribute a fix.

love this man! thanks