1

I am using a node.js express framework and initially wrote the get database password/hash and compare form password/hash in one route file. Now I want to pass a userName to a separate module. The module should accept a userName and return the corresponding password/hash from the database.

Before breaking the functions out into their own modules, we return the hash and pass it to the next function (passHash) and the code worked just fine. Now that I've separated the functions from the db calls, I cannot figure out how to return the hash back to the original function.

With the functions broken out into two separate files, I can successfully pass userName to the database module (it console logs the username/hash), but I cannot return the user's password/hash back to the original function in the original route. I've read many posts on how to use require to pass "OR" return variables/objects from one module to another, but nothing on how to pass a variable "AND" return the post function data.

Here are some of the resources that I consulted when creating these files

1.) Accepted answer was easy to follow (this is the model I used)

2.) Advanced

3.) Example most answers show one way return functions

4.) Seems to have the answer

Additionally, I have tried returning the password/hash in several arrangements; Create an object and return properties. Return the object, and assign the object to a variable and extract the property similar to link 4 Above.

Below are:

1.) The Modularized Database function (databaseLoginUser.js)

2.) The Original Route that calls the Modularized function (databaseLogin.js)

3.) The console output (no error just hangs waiting for the next function)

//databaseLoginUser.js

var express = require('express');
var router = express.Router();
var mysql = require('mysql');

module.exports.getModuleFunction = function(userName, callback) {
  queryUser(userName);

  function queryUser(userName) {
    console.log('In Query User; ');
    var database = mysql.createConnection({
      host: "xxx.xxx.xxx.xxx",
      port: "3306",
      user: "UserName",
      password: "Password",
      database: "Students",
      multipleStatements: true
    });

    database.connect();

    console.log('test');

    database.query('SELECT StudentUsername, StudentPassword FROM STUDENT WHERE StudentUsername = ?', userName, function(err, rows, fields) {
      if (err) {
        console.log(err);
      }
      //console.log(rows);
      console.log('Database Returned User: ' + rows[0].StudentUsername);
      console.log('Database Returned Password: ' + rows[0].StudentPassword);
      var hashFromDatabaseBuffer = Buffer.from(rows[0].StudentPassword);
      returnPassHash(hashFromDatabaseBuffer);
      return returnPassHash;
    })

    function returnPassHash(hashFromDatabaseBuffer) {
      console.log('Do I get here?; ');
      return hashFromDatabaseBuffer;
    }
  }
};

queryPass is the function that calls and returns the other module's password property, and I have written this a few different ways, but settled on posting this version of the function call for brevity.

//loginUser.js
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var bodyParser = require('body-parser');
var async = require('async');
var app = express();
var expressValidator = require('express-validator');
var securePassword = require('secure-password');
var database = require('./db');
var queryPass = require('./databaseLoginUser');

router.get('/', function(req, res, next) {
  'use strict';
  console.log('in the login user get route');
  res.render('signUp');
});

router.post('/', function(req, res, next) {
  'use strict';
  console.log('in Login Route');
  var userName = req.body.userName;
  var preHashPass = req.body.password;

  queryPass.getModuleFunction(userName, function(data) {
    passHash('', '', data)
  });

  function passHash(userName, preHashPass, hashFromDatabaseBuffer) {
    // Initialise our password policy
    var pwd = securePassword()
    var postPassHash = Buffer.from(preHashPass);

    // Register user
    pwd.hash(postPassHash, function(err, hash) {
      if (err) throw err
      // Save hash somewhere
      console.log('Form Password Hashed:');
      console.log(hash);

      pwd.verify(postPassHash, hashFromDatabaseBuffer, function(err, result) {
        console.log('Verify Result: ');
        console.log(result);
        if (err) throw err
        if (result === securePassword.INVALID) {
          return res.render('index');
          return console.log('Imma call the cops')
          res.render('index');
        } else {
          if (result === securePassword.INVALID_UNRECOGNIZED_HASH) return console.error('This hash was not made with secure-password. Attempt legacy algorithm')
          if (result === securePassword.VALID) console.log('Yay you made it')
          if (result === securePassword.VALID_NEEDS_REHASH) {
            console.log('Yay you made it, wait for us to improve your safety')

            pwd.hash(hashFromDatabase, function(err, improvedHash) {
              if (err) console.error('You are authenticated, but we could not improve your safety this time around')

              // Save improvedHash somewhere
              hash = improvedHash;
            })
          }

          var verifiedHash = hash;
          console.log('verifiedHash: ');
          console.log(verifiedHash);

          //Give User Auth Token Here
          console.log('You Get an auth Token: ');
          res.render('studentDash');
        }

      }) // pwd.verify


    });
    pwd.hash
  }; // pass hash
})

module.exports = router;

Console Output from Server (note the passwords are dummy data)

Console output

[nodemon] starting node ./bin/www 
GET /LogoWithLayersTiny.png 304 1.124 ms - - 
in Login Route 
In Query User; 
test 
Database Returned User: bb 
Database Returned Password: "HashParametersRemoved"$WItArkxi20QeSHlGhUK2lQ$PY74Axv6cOvFD‌​FiHmZ6EwT0RMgLkDOb1W‌​6CVBssE1tk 
Do I get here?
t.niese
  • 39,256
  • 9
  • 74
  • 101
  • Could not include console output because it was improperly formatted and cannot edit post. Including console output here: ` [nodemon] starting `node ./bin/www` GET /LogoWithLayersTiny.png 304 1.124 ms - - in Login Route In Query User; test Database Returned User: bb Database Returned Password: "HashParametersRemoved"$WItArkxi20QeSHlGhUK2lQ$PY74Axv6cOvFDFiHmZ6EwT0RMgLkDOb1W6CVBssE1tk Do I get here?;` – bbessembinders Oct 20 '17 at 05:02

1 Answers1

1

I think you just need to call callback in databaseLoginUser.js passing the data. Something like this:

// databaseLoginUser.js

var express = require('express');
var router = express.Router();
var mysql = require('mysql');

module.exports.getModuleFunction = function (userName, callback) {
    queryUser(userName);
    function queryUser(userName) {
        console.log('In Query User; ');
         var database = mysql.createConnection({
            host: "xxx.xxx.xxx.xxx",
            port: "3306",
            user: "UserName",
            password: "Password",
            database: "Students",
            multipleStatements: true
        });

        database.connect();

        database.query('SELECT StudentUsername, StudentPassword FROM STUDENT WHERE StudentUsername = ?', userName, function (err, rows, fields) {
            if (err) { console.log(err); }
            console.log('Database Returned User: ' + rows[0].StudentUsername);
            console.log('Database Returned Password: ' + rows[0].StudentPassword);
            var hashFromDatabaseBuffer = Buffer.from(rows[0].StudentPassword);
            callback(hashFromDatabaseBuffer); // This call.
        });
    }
};
kakamg0
  • 1,096
  • 5
  • 12
  • Thanks I will update. This makes sense since the buffer call will take some time to return. – bbessembinders Oct 20 '17 at 18:17
  • Wow thanks. This was literally that simple. I may make some changes to make the code cleaner, but this makes the main login module much less monolithic! Hopefully this will help others looking to make more modular code. – bbessembinders Nov 04 '17 at 23:58