I am writing a simple script to retrieve a password from the table and validate in node.js Here is the script
module.exports = {
login: function (email, pass) {
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('test.db');
db.get("SELECT password FROM users WHERE user_email = ?", email, function(err, row) {
if (err !== null) {
console.log("An error has occured");
return "error";
} else if(row.password === pass) {
console.log("success");
return "success";
} else {
console.log("Incorrect password");
return "failure";
}
});
}
};
The console log statements are correct when the if else cases are evaluated. However the return value is undefined.
I do not understand why the return value is undefined if the logging is done correctly.
You can't return values from a callback because doing so is meaningless. You have to pass in a callback to your login() function and call that with (err, result) inside your db.get() callback:
module.exports = {
login: function (email, pass, cb) {
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('test.db');
db.get("SELECT password FROM users WHERE user_email = ?",
email,
function(err, row) {
if (err)
return cb(err);
cb(null, row.password === pass);
});
}
};
Related
Below is the piece of code. I'm always getting initial value of valid variable as the last return statements run before the DB Query completely executes.
async login(username, password, ctx) {
let sql = 'SELECT * FROM users WHERE username=?;'
let valid = false; //I'm always getting this value
await this.db.query(sql, [username], function(err, rows, fields){
console.log(rows);
if(rows.length > 0)
{
console.log('coming into');
console.log(JSON.stringify(rows));
valid = bcrypt.compare(password, rows[0].pass)
console.log('valid is ', valid);
if(valid === false) throw new Error(`invalid password for account "${username}"`)
ctx.session.user_id = rows[0].id
ctx.session.authorised = true
return ctx.redirect(`/secure?msg=you are now logged in...`)
}
else
throw new Error(`username ${username} not found ${JSON.stringify(rows)}`);
return valid;
});
}
One way to fix this is to wrap the db-call in a promise and wait for this promise to resolve/reject. Then, you can either set the authorised-flag and redirect the user or handle the error:
async login(username, password, ctx) {
try {
const rows = await new Promise((resolve, reject) => {
let sql = 'SELECT * FROM users WHERE username=?;'
this.db.query(sql, [username], function (err, rows, fields) {
if (rows && rows.length > 0) {
console.log('coming into');
console.log(JSON.stringify(rows));
valid = bcrypt.compare(password, rows[0].pass)
console.log('valid is ', valid);
if (valid === false) {
reject(new Error(`invalid password for account "${username}"`));
}
return resolve(rows);
}
reject(new Error(`username ${username} not found ${JSON.stringify(rows)}`); )
});
});
ctx.session.user_id = rows[0].id
ctx.session.authorised = true
return ctx.redirect(`/secure?msg=you are now logged in...`)
} catch (err) {
// handle your error, e.g. ctx.redirect('/error-page')
}
}
I am building a user sign up and crud app. I have a db model.
var valid;
module.exports = {
connectDB: function(){
}
,
findUser: function(req,res) {
}
,
createUser: function(email,name,password){
var role = 'view';
var sql = "INSERT INTO `users`(email, name, password, role) VALUES (" + "'"+email+"'"+","+"'"+name+"'"+","+"'"+password+"'"+","+"'"+role+"'"+")";
db.query(sql, function(err, result){
if(err){
console.log(`FAILED: ${err}`)
return false; // tried setting valid to false
}
else
{
console.log(`User Created`);
valid = true;
}
});
return valid; // this also returns undefined
}
}
I want to be able to return a bool depending up on the succession of the query. I tried returning true/false. I did some searching on why this happens. Firstly there was an explanation about js being asynchronous.
My question is what is the correct way of returning values in function when exporting so that I can use it?
By using promises
createUser: function(email,name,password){
return new Promise(function(resolve,reject){
var role = 'view';
var sql = "INSERT INTO `users`(name, password, role) VALUES (" + "'"+email+"'"+","+"'"+name+"'"+","+"'"+password+"'"+","+"'"+role+"'"+")";
db.query(sql, function(err, result){
if(err){
console.log(`FAILED: ${err}`)
reject(err);
}
else
{
console.log(`User Created`);
resolve();
}
});
})
}
we can now use createUser like so;
db.createUser(email,name,password).then(function(){
console.log('redirect');
res.redirect('/');
}).catch(function(){
console.log('something went wrong');
res.render('signup', { message: 'something went wrong' })
});
I'm trying to create access levels in Node.js using Session. So for example, if the username is "test" it can view a certain page. If the username is "admin" it cannot view that same page. The username is stored in MySQL table "accounts". The table has the column attribute "username". Been trying to try different things but I can't seem to get it to work.
Here's my JS code:
app.get('/ViewPage', function(request, response) {
var connection = request.app.get('pool');
if (request.session.loggedin) {
var username;
connection.query('SELECT username FROM accounts WHERE username = test', function (error, results, fields) {
if (username == "test") {
// do the command here
} else if (username == "admin"){
response.redirect('/');
}
});
} else {
response.redirect('/');
}
});
Edit:
I updated my code as follows but it keeps looping to the "Admin cannot view this page" else if block.
app.get('/Create_Award', function (request, response) {
var connection = request.app.get('pool');
if (request.session.loggedin) {
connection.query('SELECT username FROM accounts', function (error, results, fields) {
{ account: results[0] };
if (error) {
console.log(error);
}
else {
if (results[0].username === "test") {
connection.query('SELECT accounts.id, accounts.username, awardType.id as awardTypeId, awardType.title FROM accounts JOIN awardType WHERE username = ?', [request.session.username], function(error, results, fields) {
response.render('Create_Award.html', { account: results[0], data: results });
console.log('Test account.');
}); //2nd connection
}
else if (results[0].username === "admin") {
response.redirect('/');
console.log('Admin cannot view this page.');
}
else {
response.redirect('/');
}
}
}); //1st connection
} else {
response.redirect('/');
}
});
app.get("/viewpage", async function(req, res) {
var connection = req.app.get("pool");
if (res.session.loggedin) {
try {
const result = await connection.query(
"SELECT * FROM accounts WHERE username = test"
);
if (result[0].username === "test") {
//something
} else if (result[0].username === "admin") {
//something
}
} catch (error) {
//You can log the error
return res.redirect("/");
}
}
return res.redirect("/");
});
There are some things to note here
1) Usage of async/await. It makes the code more readable, since queries can take some time to retrieve the data. Also encapsulating all of it inside a try/catch block so you can handle the error if there's any.
2) Your query callback wasn't used. You should use the results argument to retrieve the data in a callback-way.
3) While this is my opinion, always try to return a response, otherwise you may get "Routing error: Can't set headers after they are sent"
You are never populating your var username as it will always will be undefined and your code will go to else block
app.get('/ViewPage', function (request, response) {
var connection = request.app.get('pool');
if (request.session.loggedin) {
connection.query('SELECT username FROM accounts WHERE username = test', function (error, results, fields) {
if (error) {
console.log(error);
}
else {
if (results[0].username === "test") {
response.redirect('/myCustom');
}
else if (results[0].username === "admin") {
response.redirect('/');
}
else {
response.redirect('/');
}
}
});
} else {
response.redirect('/');
}
});
Update your code and it will work
Edit- From what I can see understand from your updated code, the only thing incorrect is how you are using res.render. have a look here, it takes a callback function
Try this in your code and let me know if it works
response.render('Create_Award.html', { account: results[0], data: results },(err,html)=>{
res.send(html)
});
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);
// ...
});
});
}
I'm trying to compare an entered email on my website, to ones in the database to see whether it already exists. If it does, then the function returns false and an error is displayed.
var db = new sqlite3.Database('users_db.db');
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (rows == undefined ){
global.returnvalue2 = false;
}
}
);
What I want is for the function to be run immediately after the selection, so that the returned value is false, and the user record is not created.
At the moment I realise that the callback is being called after everything, so its just making the selection and carrying on throughout the rest of the program until the end.
How can I check if there are any existing records with the same email?
Make use of the async features in javascript, so your code would look something like this;
var db = new sqlite3.Database('users_db.db');
function checkemail(email, cb) {
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (err || rows == undefined ){
cb("bad email", null)
} else {
cb(null,rows)
}
});
}
function checkpassword(pw,cb) {....}
function checkclass(cls,cb) {....}
and then write you code like this;
checkemail(myemail, function(err,rows) {
if (err) return alert(err);
checkpassword(pw, function(err, msg) {
if (err) return alert(err);
checkclass(cls, function(err, msg) {
if (err) return alert(err);
alert("Congratulation you passed all the checks");
});
});
});
Here's a little one I made.
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('iHacks.db');
function get_user_credentials (email, password)
{ return new Promise((rs, rj) => {
function callback (err, User)
{
if (err) rj(err);
rs(User);
}
db.get('select * from users where email=? and password=?', [email, password], callback);
}); }
function login (email, password)
{ return new Promise ((rs, rj) => {
// Hashing the password.
password = sha256(password + 'EzSalt');
// Creating an Error
const err = new Error('Email or password did not match!');
// Callback functions
function check (User)
{
rs(User);
}
function fail (err)
{
rj(err);
}
// Getting the user credentials
get_user_details(email, password).then(check).catch(fail);
}); }
login()
.then(/* Continue code */)
.catch(err => {throw new Error(err); })
;