[Solved] Completely stuck on 'Registration of New Users'

I’ve got through most of the challenges for Advanced Node and Express, but I’m stuck on the challenge where you need to set up registration of users. My app allows log in and log out in the preview, but I still can’t pass the criteria for being able to log in for some reason. My registration isn’t working at all. I was getting an error about db.collection not being a function so I moved my app.route(’/register’) into the connection to the database but I just get a 404 error. I’m losing my mind trying to figure out how to pass this. What am I missing? I’ve scoured the forums and tried so many of the suggestions, but no luck. If anyone has suggestions, please try to be as contextual as possible. Just seeing the snippets alone can be difficult on figuring out where exactly they go :sweat:
Here’s the Glitch (will expire within five days) https://hammerhead-juice-qckj5li6wtj.glitch.me

Thank you in advance!

My code
server.js

"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").Strategy;

const app = express();

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

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());

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

    passport.serializeUser((user, done) => {
      done(null, user._id); //get id from mongo
    });

    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);
        });
      })
    );
    
    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);
    });
  }
});

// Add middleware
function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next(); //move on to rest of function
  } else {
    res.redirect("/"); //send back to homepage if not authenticated
  }
}

app.route("/").get((req, res) => {
  res.render(__dirname + "/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(__dirname + "/views/pug/profile", {
    title: "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");
});

package.json

{
  "//1": "describes your app and its dependencies",
  "//2": "https://docs.npmjs.com/files/package.json",
  "//3": "updating this file will download and update your packages",
  "name": "FCC-Advanced-Node-and-Express",
  "author": "http://github.com/JosephLivengood",
  "version": "0.0.1",
  "description": "What am I about?",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.14.1",
    "cors": "^2.8.1",
    "body-parser": "^1.16.0",
    "mongodb": "^3.5.2",
    "helmet": "^3.4.0",
    "pug": "^0.1.0",
    "passport": "^0.3.2",
    "passport-local": "^1.0.0",
    "express-session": "^1.15.0"
  },
  "engines": {
    "node": "4.4.3"
  },
  "repository": {
    "type": "git",
    "url": "https://hyperdev.com/#!/project/welcome-project"
  },
  "keywords": [
    "node",
    "hyperdev",
    "express"
  ],
  "license": "MIT"
}

Browser
Chrome 78 on Windows 10

Challenge: Advanced Node and Express - Registration of New Users

Link to the challenge:
https://www.freecodecamp.org/learn/information-security-and-quality-assurance/advanced-node-and-express/registration-of-new-users

Would you mind linking the Glitch code so we can see we can fork it for troubleshooting?

Sure thing! https://glitch.com/edit/#!/hammerhead-juice-qckj5li6wtj

I’ve actually restarted the lesson in case I missed something obvious, so I’ll post again if I reach the answer first :slightly_smiling_face:

I’ve got it! I hope this helps anyone else with the same issue. Here’s where I went wrong:

  1. I kind of glazed over an earlier instruction to encapsulate everything in the mongo.connect block, meaning some lines of my code were out of scope. This was part of the problem as to why certain variables could not be recognised. Once that block is set up, EVERYTHING has to go inside it.

  2. I had seen a fair few people mentioning that the newer version of MongoDB is set up slightly different, but I couldn’t get any of the fixes to apply to my code - basically because I hadn’t done the above so it didn’t matter if I set up the connection differently!
    Here’s the post I referenced for updating my connection

You can see the newer, working version here (time-limited link) Code below for reference in future

"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());

const assert = require('assert');

// Connection URL
const url = process.env.DATABASE;

// Database Name
const dbName = 'test';

mongo.connect(url, function(err, client) {
  assert.equal(null, err);
  console.log("Connected successfully to server");
  const db = client.db(dbName);
  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);
    });
  }
});

1 Like

Thanks, brother. It worked perfectly