Skip to content

Instantly share code, notes, and snippets.

@JosephLivengood
Created February 5, 2017 02:29
Show Gist options
  • Save JosephLivengood/6c47bee7df34df9f11820803608071ed to your computer and use it in GitHub Desktop.
Save JosephLivengood/6c47bee7df34df9f11820803608071ed to your computer and use it in GitHub Desktop.
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const fccTesting = require('./freeCodeCamp/fcctesting.js');
const session = require('express-session');
const passport = require('passport');
const mongo = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID;
const LocalStrategy = require('passport-local');
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.set('view engine', 'pug')
app.use(session({
secret: process.env.SESSION_SECRET,
resave: true,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());
mongo.connect(process.env.DATABASE, (err, db) => {
if(err) {
console.log('Database error: ' + err);
} else {
console.log('Successful 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(
function(username, password, done) {
db.collection('users').findOne({ username: username }, function (err, user) {
console.log('User '+ username +' attempted to log in.');
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (password !== user.password) { return done(null, false); }
return done(null, user);
});
}
));
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/');
};
app.route('/')
.get((req, res) => {
res.render(process.cwd() + '/views/pug/index', {title: 'Hello', message: 'login', showLogin: true, showRegistration: true});
});
app.route('/login')
.post(passport.authenticate('local', { failureRedirect: '/' }),(req,res) => {
res.redirect('/profile');
});
app.route('/profile')
.get(ensureAuthenticated, (req, res) => {
res.render(process.cwd() + '/views/pug/profile', {username: req.user.username});
});
app.route('/register')
.post((req, res, next) => {
db.collection('users').findOne({ username: req.body.username }, function (err, user) {
if(err) {
next(err);
} else if (user) {
res.redirect('/');
} else {
db.collection('users').insertOne(
{username: req.body.username,
password: req.body.password},
(err, doc) => {
if(err) {
res.redirect('/');
} else {
next(null, user);
}
}
)
}
})},
passport.authenticate('local', { failureRedirect: '/' }),
(req, res, next) => {
res.redirect('/profile');
}
);
app.route('/logout')
.get((req, res) => {
req.logout();
res.redirect('/');
});
app.use((req, res, next) => {
res.status(404)
.type('text')
.send('Not Found');
});
app.listen(process.env.PORT || 3000, () => {
console.log("Listening on port " + process.env.PORT);
});
}});
@lalabee
Copy link

lalabee commented Jun 29, 2018

@eggei
Copy link

eggei commented Mar 28, 2020

This code won't pass the steps,

It looks like is related with res.redirect method. Failing tests for both steps points that out. But I couldn't resolve the issue.

@i-anshuman
Copy link

Same problem as @eggei.

@djasuncion
Copy link

// register new user
      app.post(
        "/register",
        (req, res, next) => {
          db.collection("users").findOne(
            { username: req.body.username },
            (err, user) => {
              if (err) {
                next(err);
              } else if (user) {
                res.redirect("/");
              } else {
                db.collection("users").insertOne(
                  {
                    username: req.body.username,
                    password: req.body.password
                  },
                  (err, doc) => {
                    if (err) {
                      res.redirect("/");
                    } else {
                      next(null, user);
                    }
                  }
                );
              }
            }
          );
        },
        passport.authenticate("local", { failureRedirect: "/" }),
        (req, res) => {
          res.redirect("/profile");
        }
      );

mine is working...

@i-anshuman
Copy link

Did it pass all the test cases??

@i-anshuman
Copy link

app.route("/register").post(
    (req, res, next) => {
      db.collection("users").findOne(
        { username: req.body.username },
        (err, user) => {
          if (err) {
            next(err);
          } else if (user) {
            res.redirect("/");
          } else {
            db.collection("users").insertOne(
              {
                username: req.body.username,
                password: bcrypt.hashSync(req.body.password, 12)
              },
              (err, newUser) => {
                if (err) res.redirect("/");
                else next(null, newUser);
              }
            );
          }
        }
      );
    },
    passport.authenticate("local", { failureRedirect: "/" }),
    (req, res, next) => {
      res.redirect("/profile");
    }
  );

What's wrong with it??

@djasuncion
Copy link

app.route("/register").post(
    (req, res, next) => {
      db.collection("users").findOne(
        { username: req.body.username },
        (err, user) => {
          if (err) {
            next(err);
          } else if (user) {
            res.redirect("/");
          } else {
            db.collection("users").insertOne(
              {
                username: req.body.username,
                password: bcrypt.hashSync(req.body.password, 12)
              },
              (err, newUser) => {
                if (err) res.redirect("/");
                else next(null, newUser);
              }
            );
          }
        }
      );
    },
    passport.authenticate("local", { failureRedirect: "/" }),
    (req, res, next) => {
      res.redirect("/profile");
    }
  );

What's wrong with it??

any error msgs?

@djasuncion
Copy link

Did it pass all the test cases??

yes

@robfuncken
Copy link

robfuncken commented Apr 8, 2020

I also cannot get the tests to pass on "Registering should work. Login should work.". But I cannot also login. Any tips?

"use strict";

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

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.set("view engine", "pug");

app.use(
session({
secret: process.env.SESSION_SECRET,
resave: true,
saveUninitialized: true
})
);
app.use(passport.initialize());
app.use(passport.session());

mongo.connect(process.env.DATABASE, (err, database) => {
const db = database.db('test')

if (err) {
console.log("Database error: " + err);
} else {
console.log("Successful 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(function(username, password, done) {
    db.collection("users").findOne({ username: username }, function(
      err,
      user
    ) {
      console.log("User " + username + " attempted to log in.");
      if (err) {
        return done(err);
      }
      if (!user) {
        return done(null, false);
      }
      if (password !== user.password) {
        return done(null, false);
      }
      return done(null, user);
    });
  })
);

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }
  res.redirect("/");
}

app.route("/").get((req, res) => {
  res.render(process.cwd() + "/views/pug/index", {
    title: "Home page",
    message: "login",
    showLogin: true,
    showRegistration: true
  });
});

app.route('/login')
      .post(passport.authenticate('local', { failureRedirect: '/' }),(req,res) => {
           res.redirect('/profile');
      });

app.route("/logout").get((req, res) => {
  req.logout();
  res.redirect("/");
});

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

// register new user
  app.post(
    "/register",
    (req, res, next) => {
      db.collection("users").findOne(
        { username: req.body.username },
        (err, user) => {
          if (err) {
            next(err);
          } else if (user) {
            res.redirect("/");
          } else {
            db.collection("users").insertOne(
              {
                username: req.body.username,
                password: req.body.password
              },
              (err, doc) => {
                if (err) {
                  res.redirect("/");
                } else {
                  next(null, user);
                }
              }
            );
          }
        }
      );
    },
    passport.authenticate("local", { failureRedirect: "/" }),
    (req, res) => {
      res.redirect("/profile");
    }
  );

app.use((req, res, next) => {
  res
    .status(404)
    .type("text")
    .send("Not Found");
});

app.listen(process.env.PORT || 3000, () => {
  console.log("Listening on port " + process.env.PORT);
});

}
});

@khanmr
Copy link

khanmr commented Apr 10, 2020

Finally got it to work. Had to delete the user freeCodeCampTester from my database and re-submit.

@robfuncken
Copy link

Finally got it to work. Had to delete the user freeCodeCampTester from my database and re-submit.

How did you fix the "db.collection is not a function" error? Can you share your code?

@khanmr
Copy link

khanmr commented Apr 11, 2020

Here is my project. You have to add secret and mongodb username and password as a string in .env. Also, when connecting mongodb, you have to use nodejs version 2.2.

https://glitch.com/edit/#!/scalloped-cyan-airship

@robfuncken
Copy link

Here is my project. You have to add secret and mongodb username and password as a string in .env. Also, when connecting mongodb, you have to use nodejs version 2.2.

https://glitch.com/edit/#!/scalloped-cyan-airship

Thanks! I finally got it to work: FCC wasn't verifying on Safari, but worked in Chrome (on OSX)

@hugoaf
Copy link

hugoaf commented Apr 17, 2020

For those having problems, three thing to check:

  1. "db.collection is not a function" error?
    get the db from the client
mongo.connect(process.env.MONGO_URI, (err, client) => {
  let db = client.db("yourproject");
  1. Having problems with redirect to home page after logout.
    see this post: https://www.freecodecamp.org/forum/t/advanced-node-and-express-test-for-redirect-keeps-failing/323024/3
    the home page need the actual title to be "Home Page"

  2. Failing user registrarion,
    As mentioned above, testing user registration more than once, require a manual deletion of the database document with username: freeCodeCampTester, otherwise will fail to register.

@ExtraLime
Copy link

ExtraLime commented Apr 22, 2020

@hugoaf
I would also like to add an alternative for '1':
You can change your URI sting to :
DB_URI='mongodb://userId:password@fcc-shard-00-00-9ev4g.mongodb.net:27017,fcc-shard-00-01-9ev4g.mongodb.net:27017,fcc-shard-00-02-9ev4g.mongodb.net:27017/test?ssl=true&replicaSet=FCC-shard-0&authSource=admin&retryWrites=true&w=majority'

Note: you can get this string by logging into mongo atlas and specifying your node version while connecting an application.

The example was started with mongo version 2.2.22. But since the example the version change to mongo 3.0+,the function no longer returns the db.

You can alternatively downgrade mongo to 2.2.22 and keep the syntax.

Glad I found this thread.

@dpsarrou
Copy link

For those struggling with this (and the other) challenges, I hear you.
Unfortunately, the automated tests that are checking for the correct solution are poorly written. The instructions for the challenge are also sometimes incomplete. I managed to pass this challenge after it was failing for 10 consecutive times with errors as mentioned on this thread, then it just passed! Literally, no code was changed.

You can find the tests and what they are exactly testing at this repo. No more surprises such as a check for a Home page text no one told you to add. Also no more frustration for you when providing a correct solution by defining routes with app.get() when the test was actually testing for the equivalent app.route().get().

@DannStormy
Copy link

freeCodeCampTester

Please, how did you do this exactly?

@TheHexorcist
Copy link

For those struggling with this (and the other) challenges, I hear you.
Unfortunately, the automated tests that are checking for the correct solution are poorly written. The instructions for the challenge are also sometimes incomplete. I managed to pass this challenge after it was failing for 10 consecutive times with errors as mentioned on this thread, then it just passed! Literally, no code was changed.

You can find the tests and what they are exactly testing at this repo. No more surprises such as a check for a Home page text no one told you to add. Also no more frustration for you when providing a correct solution by defining routes with app.get() when the test was actually testing for the equivalent app.route().get().

Don't forget about all the problems with glitch! Sometimes I have to refresh glitch several times and then re-run the challenge test to get things to pass.

@mospaulchoi
Copy link

For those having problems, three thing to check:

  1. "db.collection is not a function" error?
    get the db from the client
mongo.connect(process.env.MONGO_URI, (err, client) => {
  let db = client.db("yourproject");
  1. Having problems with redirect to home page after logout.
    see this post: https://www.freecodecamp.org/forum/t/advanced-node-and-express-test-for-redirect-keeps-failing/323024/3
    the home page need the actual title to be "Home Page"
  2. Failing user registrarion,
    As mentioned above, testing user registration more than once, require a manual deletion of the database document with username: freeCodeCampTester, otherwise will fail to register.

Thank you very much! Advice 1 helped a lot.
How to manually delete username: freeCodeCampTester from database: go to mongodb.com => cluster => collections => users !

@mospaulchoi
Copy link

freeCodeCampTester

Please, how did you do this exactly?

How to manually delete username: freeCodeCampTester from database:
go to mongodb.com => cluster => collections => users !

@JonatanGarbuyo
Copy link

i lost many hours finding the errors but mi code was fine.
only small differences here and there in titles and names make to pass the test impossible.

this example passes the current test. check against your code. i hope it help someone.

server.js
//////////////////////////////////////////////////////////////////////////////
"use strict";

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

const app = express();

fccTesting(app); //For FCC testing purposes
app.use("/public", express.static(process.cwd() + "/public"));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

//Express needs to know which template engine you are using.
//We will use the set method to assign 'pug' as the 'view-engine'.
app.set('view engine', 'pug');
//app.set("views", path.join(__dirname, "views"));

//You will need to set up the session settings now and initialize Passport.
app.use(session({
secret: process.env.SESSION_SECRET,
resave: true,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());

// connect to our database then start listening for requests.
mongo.connect(process.env.DATABASE, { useUnifiedTopology: true }, (err, client) => {

const db = client.db();

if(err) {
console.log('Database error: ' + err);
} else {
console.log('Successful 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(
      function(username, password, done) {
        db.collection('users').findOne({ username: username }, function (err, user) {
          console.log('User '+ username +' attempted to log in.');
          if (err) { return done(err); }
          if (!user) { return done(null, false); }
          if (password !== user.password) { return done(null, false); }
          return done(null, user);
        });
      }
    ));
  
  
    function ensureAuthenticated(req, res, next) {
      if (req.isAuthenticated()) {
          return next();
      }
      res.redirect('/');
    };
  

    app.route('/')
      .get((req, res) => {
        res.render(process.cwd() + '/views/pug/index', {
          title: 'Home page', 
          message: 'login', 
          showLogin: true, 
          showRegistration: true});
      });
  
    app.route('/login')
      .post(passport.authenticate('local', { failureRedirect: '/' }),(req,res) => {
           res.redirect('/profile');
      });
  
    app.route('/profile')
      .get(ensureAuthenticated, (req, res) => {
           res.render(process.cwd() + '/views/pug/profile', {username: req.user.username});
      });
  
    app.route('/register')
      .post((req, res, next) => {
          db.collection('users').findOne({ username: req.body.username }, function (err, user) {
              if(err) {
                  next(err);
              } else if (user) {
                  res.redirect('/');
              } else {
                  db.collection('users').insertOne(
                    {username: req.body.username,
                     password: req.body.password},
                    (err, doc) => {
                        if(err) {
                            res.redirect('/');
                        } else {
                            next(null, user);
                        }
                    }
                  )
              }
          })},
        passport.authenticate('local', { failureRedirect: '/' }),
        (req, res, next) => {
            res.redirect('/profile');
        }
    );
  
    app.route('/logout')
      .get((req, res) => {
          req.logout();
          res.redirect('/');
      });

    app.use((req, res, next) => {
      res.status(404)
        .type('text')
        .send('Not Found');
    });

    app.listen(process.env.PORT || 3000, () => {
      console.log("Listening on port " + process.env.PORT);
    });  

}});
//////////////////////////////////////////////////////////////////////////

profile.pug
////////////////////////////////////////////////////////////////////
html
head
title FCC Advanced Node and Express
meta(name='description', content='Profile')
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 Profile Home
//add your code below, make sure its indented at this level
h2.center#welcome Welcome, #{username}!
a(href='/logout') Logout
////////////////////////////////////////////////////////////////////////

@HusrevAkbas
Copy link

app.route("/register").post(
    (req, res, next) => {
      db.collection("users").findOne(
        { username: req.body.username },
        (err, user) => {
          if (err) {
            next(err);
          } else if (user) {
            res.redirect("/");
          } else {
            db.collection("users").insertOne(
              {
                username: req.body.username,
                password: bcrypt.hashSync(req.body.password, 12)
              },
              (err, newUser) => {
                if (err) res.redirect("/");
                else next(null, newUser);
              }
            );
          }
        }
      );
    },
    passport.authenticate("local", { failureRedirect: "/" }),
    (req, res, **next**) => {
      res.redirect("/profile");
    }
  );

What's wrong with it??
Try to remove next argument in passport.authenticate()

@lofung
Copy link

lofung commented Jul 10, 2020

https://www.youtube.com/watch?v=1AzzAv8YU6Q&t=5534s

as seen on a lot of sources, the test on

  1. Create a new middleware
  2. Loggin a user out

are garbage. as long as your code is working, do not waste time passing the test.

just move on.

@geraldombuthia
Copy link

This is my code so far but i am getting an error in the 58th line, as shown in the second code , i have tried the fixes provided but i receive an error that db is not a function...Someone help, am working on it in glitch
`"use strict";

const express = require("express");
const fccTesting = require("./freeCodeCamp/fcctesting.js");
const session = require("express-session");
const passport = require("passport");
const ObjectID = require("mongodb").ObjectID;
const mongo = require("mongodb").MongoClient;
const LocalStrategy = require("passport-local");
const db = require("mongodb");
const app = express();

fccTesting(app); //For FCC testing purposes
app.use("/public", express.static(process.cwd() + "/public"));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

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

app.use(
session({
secret: process.env.SESSION_SECRET,
resave: true,
saveUnintialized: true
})
);

app.use(
session({
secret: process.env.SESSION_SECRET,
resave: true,
saveUninitialized: true
})
);
app.use(passport.initialize());
app.use(passport.session());

mongo.connect(process.env.DATABASE, (err, db) => {
if (err) {
console.log("Database error: " + err);
} else {
console.log("Successful database connection");

//serialization and app.listen
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(function(username, password, done) {
db.collection("users").findOne({ username: username }, function(err, user) {
console.log("User " + username + " attempted to log in.");
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (password !== user.password) {
return done(null, false);
}
return done(null, user);
});
})
);
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect("/");
}
app.route("/").get((req, res) => {
//Change the response to render the Pug template
res.render(process.cwd() + "/views/pug/index", {
showRegistration: true,
showLogin: true,
title: "Home Page",
message: "please login"
});
});
app
.route("/login")
.post(
passport.authenticate("local", { failureRedirect: "/" }),
(req, res) => {
res.redirect("/profile");
}
);
app.route("/profile").get(ensureAuthenticated, (req, res) => {
res.render(process.cwd() + "/views/pug/profile", {
username: req.user.username
});
});

app.route("/logout").get((req, res) => {
req.logout();
res.redirect("/");
});
app.use((req, res, next) => {
res
.status(404)
.type("text")
.send("Not Found");
});
app.route("/register").post(
(req, res, next) => {
db.collection("users").findOne({ username: req.body.username }, function(
err,
user
) {
if (err) {
next(err);
} else if (user) {
res.redirect("/");
} else {
db.collection("users").insertOne(
{
username: req.body.username,
password: req.body.password
},
(err, doc) => {
if (err) {
res.redirect("/");
} else {
next(null, user);
}
}
);
}
});
},
passport.authenticate("local", { failureRedirect: "/" }),
(req, res, next) => {
res.redirect("/profile");
}
);
app.listen(process.env.PORT || 3000, () => {
console.log("Listening on port " + process.env.PORT);
});
Second code where the error is passport.use(
new LocalStrategy(function(username, password, done) {
db.collection("users").findOne({ username: username }, function(err, user) {
console.log("User " + username + " attempted to log in.");
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (password !== user.password) {
return done(null, false);
}
return done(null, user);
});
})
);`

@rhodlib
Copy link

rhodlib commented Jul 31, 2020

mongo.connect(process.env.DATABASE, (err, db) => {

You have the problem here, "mongo.connect(process.env.DATABASE, (err, db) => {}" this glitch use mongodb 3
you need to change (err, db) to (err, client) and later you can declare a variable as db like this.
const db = client.db("my-project"); //"my-project" is an example of the name of your database in mongobd

@ganeshh123
Copy link

ganeshh123 commented Aug 4, 2020

This is also works for me, provided you use the client.db() method like @rhodlib said, if you are using the URI from MongoDB atlas.

app.route("/register").post(
  bodyParser.urlencoded({ extended: false }),
  (req, res, next) => {
    /* Check if user exists */
    db.collection("users").findOne(
      { username: req.body.username },
      (error, user) => {
        if (!error && user) {
          res.redirect("/");
        }
      }
    );

    /* Create User Document */
    db.collection("users").insertOne(
      {
        username: req.body.username,
        password: req.body.password
      },
      (error, createdUser) => {
        if (!error && createdUser) {
          next();
        }
      }
    );
  },
  passport.authenticate("local", { failureRedirect: "/" }),
  (req, res) => {
    res.redirect("/profile");
  }
);

@Faisal-Alzahrani
Copy link

The test script will try to match the words "Profile" and "freeCodeCampTester" in the server response which is a web-page sent by the redirect method. Just make sure you are sending the required information and you will pass without troubles. This script unfortunately fails sometimes for unknown reasons.

Also add this line to your database initialization code:

db = mongoClient.db("databaseName"); db.collection('users').drop();

To clear the database automatically each time you restart the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment