How does "break;" work in async function? - javascript

I was using pbkdf2-password module in my login process, and some of those code seems been stuck while running. I used async hashing function to verify users, and problem happens when user inputs wrong passwd. Just loading doesnt stop.
I tried redirecting and return when user inputs wrong passwd and it worked.
but I want to know why the break didnt work.
app.post('/login', (req, res) => {
console.log(req.body);
let userid = req.body.id;
let password = req.body.password;
console.log('userid = ', userid);
console.log('password = ', password);
console.log('userlist = ', sampleUserList);
let bFound = false;
for (let i = 0; i < sampleUserList.length; i++) {
let user = sampleUserList[i];
console.log(sampleUserList[i]);
if (userid === user.userid) {
console.log('[found] userid = ', userid);
bFound = true;
/* here's where I verify users. */
return hasher({
password: password,
salt: user.salt
}, function(err, pass, salt, hash) {
if (err) {
console.log('ERR : ', err);
}
if (hash === user.password) {
console.log('INFO : ', userid, ' logged in successfully')
req.session.user = sampleUserList[i];
req.session.save(function() {
res.redirect('/carlist');
})
return;
/* here's the code for when users input wrong passwd but still have ID */
} else {
console.log('Wrong passwd.');
}
});
}
if (bFound) break;
}
if (!bFound) {
console.log('Theres no such ID.');
}
res.redirect('/login_form');
});
else {
console.log('Wrong passwd.');
res.redirect('/login_form');
return;
}
Problem solved with this code but I want to know why the break didnt work.
no error msg but infinite loading.

The break will never be reached. The return inside the if statement will prevent all subsequent code from executing.
It also breaks out of the loop, so you can feel free to remove break, your function already does what you intended the break to do.
app.post('/login', (req, res) => {
let userid = req.body.id;
let password = req.body.password;
let bFound = false;
for (let i = 0; i < sampleUserList.length; i++) {
let user = sampleUserList[i];
if (userid === user.userid) {
bFound = true;
return hasher(/* args */); // <-- this ends execution of the login handler
}
if (bFound) break;
}
if (!bFound) {
console.log('Theres no such ID.');
}
res.redirect('/login_form');
});

Related

socket.io emit firing three times

I'll start by saying I've found several similar issues posted on this site. None of them apply to my situation though.
I have a server and client (as is the norm with node.js/socket.io) and call emit a socket event when a button is pressed. This works fine... Except it seems to emit three times (at least the server runs the function three times). I've been staring at the code for way too long at this point and need another set of eyes.
Hopefully someone has an idea.
client code:
importJS('/js/pages/admin_base.js',function(){
var restartLMC = function(io){
toggleLoad();
var user = localStorage.getItem('User');
io.emit('restart_request',{session: user});
};
AdminIO = new io('http://localhost:26266');
AdminIO.on('restart_success',function(dat){
toggleLoad();
dropInfo(dat);
});
AdminIO.on('sendError',function(dat){
dropInfo(dat,{level: 'error'});
});
AdminIO.on('restart_fail',function(dat){
toggleLoad();
dropInfo(dat,{level: 'error'});
});
$('#restart').on('click',function(){
restartLMC(AdminIO);
});
});
Admin code:
process.stdout.write('\033c');
console.log('\x1b[36m', "Admin server starting...", '\x1b[0m');
var
ini = require('node-ini')
, conf = ini.parseSync('../config.ini')
, CS = require('../lm_modules/CoreSync.js')
, CoreSync = new CS()
, checkSession = function (session, callback) {
var res;
if (!CoreSync) { throw "Fatal error, there is no connection to the Core service!"; }
if (CoreSync.sessions) {
if (CoreSync.sessions[session]) {
res = CoreSync.sessions[session];
callback(res);
}
else {
CoreSync.sync('session', function (err, dat) {
if (CoreSync.sessions[session]) {
res = CoreSync.sessions[session];
callback(res);
} else { res = false; callback(res); }
});
}
} else {
res = false; callback(res);
}
if (res === "undefined") { callback(false); }
}
, runCMD = function(cmd,errCB,callback){
var
command
, args;
if(cmd.cmd){ command = cmd.cmd; } else { command = cmd; }
if(cmd.args){ args = cmd.args; }
const spawn = require('child_process').spawn;
const ex = spawn(command, args);
ex.stdout.on('data', (data) => {
callback(data);
});
ex.stderr.on('data', (data) => {
errCB(data);
});
ex.on('close', (code) => {
});
}
, executeCMD = function(cmd,callback){
const exec = require('child_process').exec
, cdw = (__dirname + '/../');
exec(cmd, {cwd: cdw}, (err, stdout, stderr) => {
if (err) {
callback(err,null);
return;
}
callback(stderr,stdout);
});
}
, io = require('socket.io').listen(26266) // can use up to 26485
console.log('\x1b[32m', "Admin server started.", '\x1b[0m');
console.log("Admin server listening at " + "http://" + conf["Server"]["binding"] + ":26266");
io.on('connection', function (socket) {
socket.on('restart_request', function(req){
console.log('Recieved restart request');
var success = false
, session = JSON.parse(req.session)
, sessionID = session.sessionID;
checkSession(sessionID, function (ses) {
if (ses === false) { console.error('CheckSession failed: No session exists'); return; }
if (ses.user.uuid !== session.uuid) { console.error('CheckSession failed: UUID mismatched'); return; }
if (ses.user.role < conf['Permissions']['lm_restart']){ socket.emit('restart_fail','Insufficient permissions.'); return; }
if(process.platform === 'win32'){
executeCMD('cd',function(err,res){
var errSent = false;
if(err){
console.error(err);
if(!errSent){ socket.emit('sendError','Restart failed'); }
errSent = true;
if(res === null){return;}
}
console.log(res);
socket.emit('restart_success','LM successfully restarted.');
});
}
else if(process.platform === 'linux'){
}
});
});
});
For those of you who may have seen this and found it a curious question/situation... I found two parts to this.
The first part is the $().on binding. For some reason (even though it's by no means called multiple times in the js code) adding unbind() in front of the binding resolved the issue in part... it cut the extra emits down from 3 to two (until I started another server app, then it went back up to three...)
The other part I found was that (for some reason) the socket.io connection is being duplicated as many times as there are socket servers running. More details on this issue here... I believe that once the cause for this is found, my issue will be resolved.

Node.js / express, javascript callback function not getting executed

/* GET home page. */
router.get('/home/', function(req, res, next) {
var code = req.query.code;
req.SC.authorize(code, function(err, accessToken) {
if ( err ) {
throw err;
} else {
req.session.oauth_token = accessToken;
// Client is now authorized and able to make API calls
//res.render('home', { token: accessToken });
var url = 'https://api.soundcloud.com/me?oauth_token=' + accessToken;
requestify.get(url).then(function(response){
var user = response.getBody();
req.session.user = user;
var user_url = config.base_url + '/api/users/add';
var options = { user: user };
requestify.post(user_url, options).then(function(response){
console.log("done with users/add")
var href = 'https://api.soundcloud.com/users/' + user.id
+ '/favorites?client_id=' + config.auth.client_id + '&linked_partitioning=1&limit=200';
soundcloud.getCollection(req, res, [], href, function(collection){
console.log("can't get here...");
//console.log(collection);
res.json(collection);
//return collection;
});
/*
var collection_url = config.base_url + '/api/collections/add';
requestify.post(collection_url, options).then(function(response){
console.log("done with collections/add")
res.json(response);
})
*/
});
});
}
});
});
function getCollection(req, res, collection, next_href, done){
console.log("here");
requestify.get(next_href).then(function(response){
var updatedCollection = collection.concat(response.getBody().collection);
if (next_href && updatedCollection.length < 500){
var href = response.getBody().next_href;
getCollection(req, res, updatedCollection, href);
}
else {
console.log("done");
done(updatedCollection);
}
//res.json(response.getBody());
});
}
Behavior I'm seeing is, the collection is properly built up, the console.log("done") is showing up in the console, but after I call done(updatedCollection), the callback function I pass in does not get executed. No print statement, no json rendering. Do you guys see what the issue is?
You're recursively calling the getCollection function without the callback, so the next time it's called, done is undefined.
Pass on the callback to the recursive calls as well
function getCollection(req, res, collection, next_href, done) {
requestify.get(next_href).then(function(response){
var updatedCollection = collection.concat(response.getBody().collection);
if (next_href && updatedCollection.length < 500){
var href = response.getBody().next_href;
getCollection(req, res, updatedCollection, href, done); // <- HERE
} else {
console.log("done");
done(updatedCollection);
}
//res.json(response.getBody());
});
}

AngularJS & Socket.IO - Return value from Service (emit here) to Controller is undefined || promises, asynchronicity

I don't get my code to work properly.
I'm developing an app with AngularJS including a connection to a backend server via socket.io. I'm working on a login which is intended to send an user's data to the server. The server is intended to respond with "valid" and the user's data (name, dateOfBirth, ...) if the sent data is correct (email and password). Elements are:
BackendService (Factory which executes emit to server)
AppController (Controller which calls the login function of BackendService)
Node.js Server (computes if the sent data is valid so that the user can be logged in)
The intention is that the login function in the Factory returns a "login code" which tells the controller if the login is correct. Unfortunately the function returns "undefined". During my research, I found out that it might be because of asynchronicity and promises. However, I couldn't apply the given information to my problem as the majority was about $http. In addition - if the structure of my code is in need of improvement, let me know!
Here's my code:
Node.js Server
socket.on('logincust', function (p1, fn) {
connection.query("SELECT Salt FROM Customer WHERE Email = ?", [p1.Email], function (err, data, fields)
{
if (err) {
throw err;
}
if (data.length > 0) {
var hash = crypto.createHash('sha256').update(p1.Password + data[0].Salt).digest('base64');
connection.query("SELECT LName,FName,Email,Telephone,Address,DateOfBirth FROM Customer WHERE Password = ?", [hash], function (err, data2, fields) {
if (err) {
throw err;
}
if (data2.length > 0) {
fn('valid', data2[0]);
}
else {
fn('invalidpassword', 'nodata')
}
})
}
else {
fn('invalidemail','nodata')
}
})
})
BackendService (Factory)
"use strict";
mobileClientApp.factory('BackendService', function() {
var mySocket = io.connect('http://thisLinkIsPrivate:8888/ns');
return {
login: function (pUserData) {
if (mySocket.connected) {
mySocket.emit('logincust', pUserData, function (resp, data) {
if (resp == "valid") {
var parsedData = JSON.stringify(data);
console.log(parsedData);
user.lName = parsedData.LName; // Fill userData
user.fName = parsedData.FName;
user.email = parsedData.Email;
user.phoneCallcenter = parsedData.Telephone;
console.info("Login successful.");
return 0;
}
else {
if (resp == "invalidpassword") {
return 1;
}
else if (resp == "invalidemail") {
return 2;
}
}
});
}
else { // Socket is not connected
console.warn("Socket not connected.);
user.fName = "Peter";
user.lName = "Offline";
return -1;
}
};
Angular Controller
$scope.doLogin = function() {
var user = {'Email': this.loginData.username, 'Password': this.loginData.password};
var isLoggedIn = BackendService.login(user); // 0 - logged in, 1 - invalid password, 2 - invalid email, -1 - socket not connected
console.log("BackendService.login(user): " + BackendService.login(user)); // is undefined!
console.log("isLoggedIn: " + isLoggedIn); // undefined!
if (isLoggedIn == 0 || isLoggedIn == -1) {
$location.path('/app/landing');
}
else {
$scope.errorMessage = "Invalid login data!";
}
};
Yes, the problem seems to be asynchrony. If you want to have access to results from login method you should pass a callback to it. Since after you called it, the next execution will be your console log and that will happen before your SQL query returns results.

Checking login credentials against a MongoDB is not working

router.post('/checkuser', function(req, res) {
var db = req.db;
var userEmail = req.body.useremail;
var password = req.body.password;
var collection = db.get('usercollection');
collection.find( { "email": userEmail }, function (err, doc) {
if (err || !doc) {
res.redirect("login");
} else {
res.redirect("userlist");
}
});
});
This code is supposed to check the login credentials in a MongoDB and return false if the values are not matched.
But it always redirects to the userlist.jade file. Can someone please explain why?
Your code always redirects to the userlist.jade file because of the current logic in the callback function: since find() method returns a cursor, the if statement checks whether there is an error OR there is no returned cursor with the matched document, thus the variable doc is a cursor which is always returned whether there is a match or not. Use the findOne() method instead:
collection.findOne({"email": userEmail}, function(err, user) {
if( !err && user && user.password === password ) {
res.redirect("userlist");
}
else { res.redirect("login"); }
});

How do I loop through the search results and based on which ids match return true to display different info for it?

so I am trying to search through the search results and see who already exists in the friendRequest array of the user searching. If they exist then I want to change the button that displays for the user to Contact requested and disable it.
Here is my code on the route file:
exports.searchPost = function(req, res, err) {
User.find({$or:[
{firstName: req.body.firstName},
{lastName: req.body.lastName},
{email: req.body.email},
{phone: req.body.phone}]
}, function(err, users, userAdd) {
if(err) {
return res.render('searchError', {title: 'Weblio'});
} else {
if(req.body.firstName=== '' && req.body.lastName==='' && req.body.email==='' && req.body.phone=== '') {
//maybe a diff page saying that is not a valid search page
return res.render('searchError', {title: 'Weblio'});
} else {
console.log('addman');
console.log(userAdd);
console.log(users);
for(x in users) {
User.findById(req.signedCookies.userid,
{friendRequest: x.id}
if(x.id === true ) {
console.log('addman1');
return userAdd = false;
} else {
console.log('addman2');
return userAdd = true;
}
});
console.log(x);
}
console.log(userAdd);
console.log(users);
//can use this loop if want to serve the info as oppose to doing it in jade, just change users to uuser
/*var i = 0;
var uuser = [];
for(i=0; i < users.length; i++) {
uuser.push(users[i].firstName + ' ' + users[i].lastName);
};
*/
//console.log(i);
return res.render('searchResults', {title: 'Weblio',
usersFound: users,
userAdded: userAdd
});
}
}
});
};
Here is the jade file:
extends layout
block content
div
legend Search Results
div#userResults
for user in usersFound
a(href='/user/#{user.id}')
p #{user.firstName} #{user.lastName}
- if(userAdded === false)
button.addContact(data-user=user.id) Add Contact
- else
button.addContact(data-user=user.id, 'disabled'='disabled') Contact Requested

Categories