Junior
Junior

Reputation: 11990

Javascript function is returning false where it should be returning true

I wrote a node.js module. My module has an isValid method which reads data from a database using a giving token as a lookup value. If the data is valid setData method is called, then return true if the data is valid or false otherwise.

Based on some messages I logged to the console, the function should return true but when I do `if...else...`` check, it always returns false.

Here is my module

var db = require('./dbconnect');

var PHPUnserialize = require('php-unserialize');


function validator (){
  this.icws = null;
};


/**
* @setData
*
* Set the value of the icwsData
*
* @return void
*/
validator.prototype.setData = function (icws){
  this.icws = icws;
};


/**
* @getData
*
* Get the value of the icwsData
*
* @return object
*/
validator.prototype.getData = function (){
  return this.icws;
};


/**
* @isValid
*
* Checks if a token is valid or not
*
* @params (string) tokenId: the PHP sessionId
* @params (string) myIP: the user IP address
* @params (integer) duration: the duration to keep the session good for in microseconds
*
* @return bool
*/
validator.prototype.isValid = function (tokenId, myIP, duration){

  if(!tokenId || !myIP){
    console.log('Missing TokenID or IP Address');
    return false;
  }

  if(!duration){
    duration = 3600;
  }

  var self = this;
  db.sqlConnection('SELECT ' +
                   '  su.icws_username AS username ' +
                   ', su.icws_password AS password ' +
                   ', su.icws_workstation AS workstation ' +
                   ', icws.host ' +
                   ', icws.port ' +
                   ', s.data ' +
                   'FROM sessions AS s ' +
                   'INNER JOIN view_users AS su ON su.user_id = s.user_id ' +
                   'INNER JOIN icws_servers AS icws ON icws.server_id = su.icws_server_id ' +
                   'WHERE s.session_id = ? '
                   , [tokenId] , function(err, rows){


    if(err){ 
      console.log(err);
      return false;
    }

    if(!rows[0] || !rows[0].data){
      console.log('No match found for this token!');
      return true;
    }

    var data = PHPUnserialize.unserializeSession(rows[0].data);
    var now = Math.floor(new Date() / 1000);

    if(!data.MA_IDLE_TIMEOUT || (data.MA_IDLE_TIMEOUT + duration) < now){
      console.log('The session Times out!');
      return false;
    }

    if(!data.MA_IP_ADDRESS || myIP != data.MA_IP_ADDRESS){
      console.log('This session have been hijacked!');
      return false;
    }

    self.setData(rows[0]);
    console.log('Good - return true!');
    return true;
  });

};


module.exports = validator;

Here is how I call the module

var sessionValidator = require('./modules/validator.js');
var sessionChecker = new sessionValidator();
var boo = sessionChecker.isValid(decodedToken, myIP, env.session.duration);
if(boo){
    console.log('Worked!');
} else {
    console.log('No Go!');
}

return;

The console prints

Good - return true!
No Go!

I am expecting this for my output

Good - return true!
Worked!

Why this function is always returning false?

If you need to see my dbconnect module, here is it's code

// Dependencies
var mysql   = require('mysql'),
    env  = require('./config');

/**
 * @sqlConnection
* Creates the connection, makes the query and close it to avoid concurrency conflicts.
*
* @param (string) sql: the sql query
* @param (array) values: contains values to sanitize for the query
* @param (function) next: call back function that will have data set if a select query is passed
*
* @return void
*/  

exports.sqlConnection = function (sql, values, next) {

    // It means that the values hasnt been passed
    if (arguments.length === 2) {
        next = values;
        values = null;
    }

    var connection = mysql.createConnection({
          host: env.mysql.host,
          user: env.mysql.user,
          password: env.mysql.password,
          database: env.mysql.database
    });

    connection.connect(function(err) {
        if (err !== null) {
            console.log("[MYSQL] Error connecting to mysql:" + err );
        }
    });

    connection.query(sql, values, function(err) {

        connection.end(); // close the connection

        if (err) {
            throw err;
        }

        // Execute the callback
        next.apply(this, arguments);
    });
}

EDITED

the current output is actually

No Go!
Good - return true!

Upvotes: 1

Views: 1988

Answers (1)

Dave Newton
Dave Newton

Reputation: 160191

The DB access itself is asynchronous.

What actually happens is that isValid returns undefined (falsey, but not explicitly false) so the conditional indicates invalidity.

It often makes sense to use === and check for type as well as truthy/falsey: it might have helped indicate why/where the code wasn't doing what you expected.

As indicated in the comments, using callbacks or promises is the canonical approach.

Upvotes: 2

Related Questions