I dont see whats the error here: it returns
Undefined
"Unknown user"
passport.use(new LocalStrategy(
function(username, password, done) {
process.nextTick(function () {
findByUsername(username, function(err, user) {
if (err) {
console.log(err);
return done(err);
}
if (!user) {
console.log("Unknown user");
return done(null, false, { message: 'Unknown user ' + username });
}
if (user.password != password) {
console.log("Invalid password");
return done(null, false, { message: 'Invalid password' });
}
return done(null, user);
})
});
}));
function findByUsername(username, fn) {
var user = [];
connection.query('SELECT * FROM Users WHERE username = ?', [username], function(err, rows) {
//console.dir(rows);
if(err != null) {
//res.end("Query error:" + err);
console.log("Query error:" + err);
} else {
for (var i = 0; i < rows.length; i++) {
var myRows = rows[i];
user.push(myRows);
};
}
});
console.log(user);
console.log(user.username);
if (user.username) {
return fn(null, user.username);
} else {
return fn(null, null);
}
}
You are passing user.username in callback. Instead you should pass user object.
Edit: You should invoke the callback only after the query is executed.
function findByUsername(username, fn) {
var user = [];
connection.query('SELECT * FROM Users WHERE username = ?', [username], function (err, rows) {
//console.dir(rows);
if (err != null) {
//res.end("Query error:" + err);
console.log("Query error:" + err);
} else {
for (var i = 0; i < rows.length; i++) {
var myRows = rows[i];
user.push(myRows);
};
}
console.log(user);
console.log(user.username);
if (user.username) {
return fn(null, user);
} else {
return fn(null, null);
}
});
}
Related
The following code is the same code used in the node-oracledb GitHub examples, called select1.js. I just modified it a little bit.
module.exports = function() {
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
this.queryDB = function (query) {
oracledb.getConnection({
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
}, function(err, connection) {
if (err) {
console.error(err.message);
return;
}
connection.execute(query, function(err, result) {
if (err) {
console.error(err.message);
doRelease(connection);
return;
}
console.log(result.metaData);
console.log(result.rows);
doRelease(connection);
return result.rows
});
});
function doRelease(connection) {
connection.release(function(err) {
if (err) {
console.error(err.message);
}
});
}
}
}
This can be used as follow:
require('./dbquery.js')();
console.log(queryDB("SELECT * FROM users"));
I expected to see the same 2D matrix (representing the table) as on line "console.log(result.rows);". But the "console.log(queryDB("SELECT * FROM users"));" returns "undefined".
How can I return a value that I get in the callback function?
I tried to add a variable X at the beginning, like this:
module.exports = function() {
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
this.queryDB = function (query) {
var X;
oracledb.getConnection({
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
}, function(err, connection) {
if (err) {
console.error(err.message);
return;
}
connection.execute(query, function(err, result) {
if (err) {
console.error(err.message);
doRelease(connection);
return;
}
console.log(result.metaData);
console.log(result.rows);
doRelease(connection);
X = result.rows
});
});
function doRelease(connection) {
connection.release(function(err) {
if (err) {
console.error(err.message);
}
});
}
return X;
}
}
But this is still undefined. How can I achieve this ?
It's running in async nature. You can resolve it with callback or promises. You can't get value like this.
pass the callback and return with callback
module.exports = function(callback) {//pass callback function and return with this
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
this.queryDB = function(query,callback) {
oracledb.getConnection({
user: dbConfig.user,
password: dbConfig.password,
connectString: dbConfig.connectString
}, function(err, connection) {
if (err) {
console.error(err.message);
return callback(err);
}
connection.execute(query, function(err, result) {
if (err) {
console.error(err.message);
doRelease(connection);
return;
}
console.log(result.metaData);
console.log(result.rows);
doRelease(connection);
return callback(null, result.rows)
});
});
function doRelease(connection) {
connection.release(function(err) {
if (err) {
console.error(err.message);
return callback(err);
}
});
}
};
};
I need to do this to log into SalesForce Databases and pass a query. Now I will be passing a lot of queries on many routers of express.js and its a real pain to login in every router. Please let me know if you know how I can avoid this.
var conn = new jsforce.Connection({
oauth2 : salesforce_credential.oauth2
});
var username = salesforce_credential.username;
var password = salesforce_credential.password;
// I want to avoid this login on every router
conn.login(username, password, function(err, userInfo) {
if (err) {
return console.error(err);
}
conn.query("SELECT id FROM Sourcing__c WHERE id = 'req.session.ref'",function(err, result) {
if (err) {
return console.error(err);
}
if(result.records.length === 0){
req.session.ref = "";
}
var body = {
"Auth__c": req.user.id,
"Stus__c": "Pending - New Hire",
"Record": "012lvIAC",
"Sourcing__c": req.session.ref
};
conn.sobject("SFDC_Employee__c").create(body, function(err, ret) {
if (err || !ret.success) {
return console.error(err, ret);
}
console.log("Created record id : " + ret.id);
// ...
});
});
});
You may save the login status and check it every time when do a query,
here I add a property on conn (the instance of 'jsforce.Connection'), I'm not sure but I think there may be a method or property that show the login status of the 'conn', you may dig into its documents.
var conn = new jsforce.Connection({
oauth2 : salesforce_credential.oauth2
});
var username = salesforce_credential.username;
var password = salesforce_credential.password;
conn._isLogin = false;
// here in your route handler
if (!conn._isLogin) {
conn.login(username, password, function(err, userInfo) {
if (err) {
return console.error(err);
}
conn._isLogin = true;
doQuery(conn);
});
} else {
doQuery(conn);
}
function doQuery (conn) {
conn.query("SELECT id FROM Sourcing__c WHERE id = 'req.session.ref'",function(err, result) {
if (err) {
return console.error(err);
}
if(result.records.length === 0){
req.session.ref = "";
}
var body = {
"Auth__c": req.user.id,
"Stus__c": "Pending - New Hire",
"Record": "012lvIAC",
"Sourcing__c": req.session.ref
};
conn.sobject("SFDC_Employee__c").create(body, function(err, ret) {
if (err || !ret.success) {
return console.error(err, ret);
}
console.log("Created record id : " + ret.id);
// ...
});
});
}
Server js:
var user_controller = require('./controllers/user_controller');
passport.use(new passportLocal(function(username, password, done) {
user_controller.login(username, password).then(function(value) {
if (value) {
console.log(value + "true")
done(null, {
id: username,
name: username
});
} else {
console.log(value + "false");
done(null, null);
}
})
}));
USer contoller:
module.exports.login = function(username, password) {
var status;
var userid = username;
User.findOne({
'username': [userid],
'password': [password]
}, function(err, user) {
if (!user) {
console.log("logged err");
status = false;
} else {
console.log("login in");
status = true;
}
console.log(status);
return status;
});
};
I am doing an async task (db call) in my user_controller.login and it returns a boolean "value"
But when I execute this I am getting error:Cannot read property 'then' of undefined
I saw previous questions on this error but couldnt understand it
I think you can try with callback function. The login function takes one callback param and execute that function at end.
module.exports.login = function(username, password, callback) {
var status;
var userid = username;
User.findOne({
'username': [userid],
'password': [password]
}, function(err, user) {
if (!user) {
console.log("logged err");
status = false;
} else {
console.log("login in");
status = true;
}
console.log(status);
callback(status);
});
};
While calling the function login pass the third param as a callback function.
var user_controller = require('./controllers/user_controller');
passport.use(new passportLocal(function(username, password, done) {
user_controller.login(username, password, function(value) {
if (value) {
console.log(value + "true")
done(null, {
id: username,
name: username
});
} else {
console.log(value + "false");
done(null, null);
}
})
}));
Note: I am not tested the above code.
You can create promise based functions in Nodejs using Q library.
npm install q
Below code can help you.
module.exports.login=function(username,password){
var status;
var userid=username;
User.findOne({'username':[userid], 'password':[password]},function(err,user){
var deferred = Q.defer();
if(err){
deferred.reject(err);
} else{
deferred.resolve(data);
}
return deferred.promise;
});
and use it in Server.js
var user_controller = require('./controllers/user_controller');
passport.use(new passportLocal(function(username, password, done) {
user_controller.login(username, password).then(function(user) {
done(null, {
id: username,
name: username
});
});
I can use the following to save a new document to my mongodb database.
User.prototype.save = function (fn) {
var user = new userModel({
user: this.user,
pass: this.pass
});
console.log('user: ' +user);
this.hashPassword (user.pass, function (err, salt, hash) {
if (err) return fn (err);
this.pass = hash;
user.salt = salt;
user.pass = hash;
user.save (function (err, product, numberAffected) {
if (err) return fn (err);
return fn(undefined);
});
});
};
Now I'm trying to check if the user already exists before saving it
User.prototype.save = function (fn) {
// See if the username exists
userModel.findOne ({ 'user': this.user }, function (err, user) {
if (err) return fn (err);
if (!user) {
user = new userModel({
user: this.user,
pass: this.pass
});
console.log('user: ' +user);
this.hashPassword (user.pass, function (err, salt, hash) {
if (err) return fn (err);
this.pass = hash;
user.salt = salt;
user.pass = hash;
user.save (function (err, product, numberAffected) {
if (err) return fn (err);
return fn(undefined);
});
});
} else {
// TODO: update all the user fields
console.log ('user already exists');
}
});
}
this.hashPassword is no longer found TypeError: Object #<Promise> has no method 'hashPassword' and the fields of user are now undefined. How can I use this within these callbacks?
EDIT 1:
Taking a closer look I also notice that this.pass = hash; in the first snippet also does nothing to the object I care about.
on line 2
var self = this
then,
self.hashPassword()
In full:
User.prototype.save = function (fn) {
var self = this;
// See if the username exists
userModel.findOne ({ 'user': self.user }, function (err, user) {
if (err) return fn (err);
if (!user) {
user = new userModel({
user: self.user,
pass: self.pass
});
console.log('user: ' +user);
self.hashPassword (user.pass, function (err, salt, hash) {
if (err) return fn (err);
self.pass = hash;
user.salt = salt;
user.pass = hash;
user.save (function (err, product, numberAffected) {
if (err) return fn (err);
return fn(undefined);
});
});
} else {
// TODO: update all the user fields
console.log ('user already exists');
}
});
}
I have the following code:
var Company = function(app) {
this.crypto = require('ezcrypto').Crypto;
var Company = require('../models/company.js');
this.company = new Company(app);
}
// Create the company
Company.prototype.create = function (name, contact, email, password, callback) {
this.hashPassword(password, function(err, result) {
if (err) throw err;
console.log(this.company); // Undefined
this.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
});
}
// Get company with just their email address
Company.prototype.hashPassword = function (password, callback) {
if(typeof password !== 'string') {
var err = 'Not a string.'
} else {
var result = {
password: this.crypto.SHA256(password)
};
}
if (err) {
return callback(err);
}
return callback(null, result);
}
module.exports = Company;
The problem is that this.company is undefined on line 11 of that code block.
I know this is not what I think, but I'm not sure how to refactor to get access to the correct this.
so theres 2 solution's to this
first the dirty one
Company.prototype.create = function (name, contact, email, password, callback) {
var that = this; // just capture this in the clojure <-
this.hashPassword(password, function(err, result) {
if (err) throw err;
console.log(that.company); // Undefined
that.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
});
}
and the clean one using bind https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
Company.prototype.create = function (name, contact, email, password, callback) {
this.hashPassword(password, (function(err, result) {
if (err) throw err;
console.log(this.company); // Undefined
this.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
}).bind(this));
}
You can reference this through another variable by declaring it in the Company.create scope, like this:
// Create the company
Company.prototype.create = function (name, contact, email, password, callback) {
var me = this;
this.hashPassword(password, function(err, result) {
if (err) throw err;
console.log(me.company); // Undefined - not anymore
me.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
});
}
Untested, but it should work like this.