Am a newbie to node.js, have somewhat figured out the LDAP authentication. Here am trying to retrieve employee ID from the search but none of the search entries are fetched though the passed credentials are bounded successfully , not sure where i'm mislead. If someone could help me out in it would be of a great help!
Below are the result sets of the code snippet:
Reader bind succeeded
Search results length: 0
Search
retval:{"messageID":2,"protocolOp":"LDAPResult","status":0,"matchedDN":"","errorMessage":"","referrals":[],"controls":[]}
No unique user to bind
ldapRoute.route('/ldap').post((req, res, next) => {
var result = "";
var email =req.body.email;
var client = ldap.createClient({
url: 'ldap://******'
});
var opts = {
filter: '(sAMAccountName='+ email + ')',
attributes: ['sAMAccountName']
};
var username = 'ii' + "\\" + email;
client.bind(username, req.body.password, function(err) {
if (err){
result += "Reader bind failed " + err;
res.send(result);
return;
}
else{
result += "Reader bind succeeded\n";
}
client.search('OU=emp,dc=i,dc=ac,dc=com', opts, function(err, searchRes) {
var searchList = []
if (err) {
result += "Search failed " + err;
res.send(result);
return;
}
searchRes.on("searchEntry", (entry) => {
result += "Found entry: " + entry + "\n";
searchList.push(entry);
});
searchRes.on("error", (err) => {
result += "Search failed with " + err;
res.send(result);
});
searchRes.on("end", (retVal) => {
result += "Search results length: " + searchList.length + "\n";
for(var i=0; i<searchList.length; i++)
result += "DN:" + searchList[i].employeeID + "\n";
result += "Search retval:" + retVal + "\n";
if (searchList.length == 1) {
client.bind(searchList[0].employeeID, req.body.password, function(err) {
if (err)
result += "Bind with real credential error: " + err;
else
result += "Bind with real credential is a success";
res.send(result);
}); // client.bind (real credential)
} else {
result += "No unique user to bind";
res.send(result);
}
});
});
});
});
The issue was in the filters and for some strange reasons the 'end' got fired before hitting the 'searchEntry', debugging it helped me to resolve the issue.
//Filter
var opts = {
filter: '(sAMAccountName=' + email+')',
scope: 'sub',
attributes: ['employeeID']
};
//Search
client.search('OU=empl,dc=ii,dc=ac,dc=in', opts, function(err, searchRes)
{
if (err)
{
result += "Search failed " + err;
res.send(result);
return;
}else{
searchRes.on("searchEntry", (entry) =>
{
result += "Found entry: " + entry.object.employeeID;
res.send(result);
}
/ ........../
} });
Related
As part of my project, I have to create text files which have to be downloaded as a ".txt".
I am using Node.js and React JavaScript, and I have already tried using the Node.js "fs.writeFile", but the browser doesn't recognize the download, the file name is always being called as the folder name and the file is always empty although the variable is a string and not empty.
I'm calling from the client to this function:
app.post("/downloadnetworks", async (req, res) => {
let selectedApps=req.body.selectedApps;
let arr=await sqlFunctions.createByIds(selectedApps);
res.send();
module.exports.createByIds = (productsArray) => {
return new Promise(function(resolve, reject) {
var bulkedString = '';
var product;
for (let obj of productsArray) {
let query = "select * from...........";
con.query(query, function(err, result, fields) {
if (err) throw err;
let stringifiedJson = JSON.stringify(result)
let parsedJson = JSON.parse(stringifiedJson)
The DB data is being added into the variable 'stringifiedJson', and it continues from here:
let parsedJson = JSON.parse(stringifiedJson) //has all the data from the DB
for (let network of parsedJson) {
if (network.certification_Id) {
bulkedString += network.domain_Name + ", " + network.publisher_Id + ", " + network.relationship + ", " + network.certification_Id;
} else {
bulkedString += network.domain_Name + ", " + network.publisher_Id + ", " +
network.relationship;
}
bulkedString += "\n";
product = network.product;
}
})
fs.writeFile('C:\Work\App ads.txt\App-Ads Files\'' + product + '.txt', bulkedString, 'utf8', (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
}
resolve(bulkedString)
})
}
I have the code below:
exports.getMyPets = function (req, res){
var email = req.body.email;
var result = [{}];
Owner.findOne({"email" : email }, "_id", function(err, owner){
if(err)
res.send(err);
console.log("Owner: " + owner._id + "\n");
Pet.find({"OwnerId": owner._id}, function(err, pet) {
if(err)
res.send(err)
var index = pet.length;
var empty = false;
if(index > 0)
empty = true;
try{
for (let x = 0; x < index; x += 1){
PetPicture.findOne({"petId" : pet[x]._id}, function (err, petPic){
console.log('pet ID: ' + pet[x]._id);
result[x] = {
name: pet[x].name,
breed: pet[x].breed,
description: pet[x].description,
imageType: petPic.imageType,
imageData: petPic.imageType
};
}); //end of petPicture.findOne
console.log('X : ' + pet[x]._id);
}// end of for loop
} catch (error){
console.log(error);
}
}
while(true){
if (result.length === index)
break;
}
if(!empty){
res.json(pet);
} else {
res.json(result);
}
}); // end of Pet,find
}); // end of petOwner.findOne
};
The block of PetPicture.findOne (the whole try catch block) does not get executed when I try to call it on endpoint. It does not log anything, not even an error on the catch part. What can I do to debug this?
I have a socket function defined as
var funcs = require('./funcs');
socket.on(EVENT_ACCEPT_ORDER, function(data, callback)
{
data = JSON.parse(data);
var bookingId = data.bookingId;
var userId = data.userId;
console.log("Accepting booking...." + bookingId);
var query = "UPDATE bookings SET bookingStatus = " + BOOKING_STATUS_ACCEPTED + " WHERE id = " + bookingId + " AND bookingStatus = " + BOOKING_STATUS_IN_QUEUE;
con.query(query, function(err, rows,fields)
{
if(err)
{
console.log("mysql query error");
}
else
{
if(rows.changedRows > 0)
{
var indexOfUser = usersList.indexOf(userId);
if(indexOfUser > -1)
{
userSockets[indexOfUser].emit(EVENT_USER_ORDER_ACCEPTED);
}
callback({"message": "Success","error":false, "booking": funcs.getBooking(con, bookingId)});
}
else
callback({"message": "Success","error":true});
}
});
});
Funcs is defined as
module.exports = {
"getBooking": function (con, bookingId)
{
var query = "SELECT * FROM bookings WHERE id = " + bookingId + " LIMIT 1";
con.query(query, function(err, rows,fields)
{
if(err)
{
console.log("mysql query error");
}
else if (rows.length == 1)
{
var booking = rows[0];
var userId = rows[0]['userId'];
var query = "SELECT id, name, phone, imagePath FROM users WHERE id = " + userId + " LIMIT 1";
con.query(query, function(err, rows,fields)
{
if(err)
{
console.log("mysql query error");
}
else if (rows.length == 1)
{
booking['user'] = rows[0];
return booking;
}
});
}
});
}
}
Everything is running fine except
callback({"message": "Success","error":false, "booking": funcs.getBooking(con, bookingId)});
in this function instead of booking, i am only getting
{"error":false,"message":"Success"}
Why am i not getting the booking function result?
You are not getting the result, because the result of the callback function in con.query is not returned to the caller of getBooking. It is the asynchronous pattern, which you are not processing correctly.
The way it is supposed to work is that the getBooking gets an extra argument: a function to be called when data are available (in an internal asynchronous call to con.query). Such a function is then provided by the caller and in this function you do whatever you want with the data:
funcs.js
"getBooking": function (con, bookingId, callback) {
...
con.query(query, function(err, rows,fields) {
...
// instead of return booking do
callback(err, booking);
...
}
}
main module
// instead of
callback({"message": "Success","error":false, "booking": funcs.getBooking(con, bookingId)});
// do
funcs.getBooking(con, bookingId, function(err, booking) {
callback({"message": "Success","error":false, "booking": booking});
});
I am afraid this is not the only issue in your code, but this should be the first to fix. Read further about processing asynchronous calls in general and specifically in node.js and fix other places in your code correspondingly.
I have a function getthem() that checks a mongo db for listings and returns name,streamurl for it.
I pass those as var stream to the renderme that renders the /dashboard page.
My problem is that i get the console.log("END OF FIND:"+JSON.stringify(stream))
to show my test input, but nothing goes to the render.
im using ejs to render. How can i get the result passed to the page ?
router.get('/dashboard', function (req, res) {
var foo = getthem();
function getthem() {
var group = "tesint";
console.log('geting for group : ' + group);
var mdlListings = require('../models/listings.js');
var myresult = "tet";
mdlListings.find({}, "name streamurl", function (err, data) {
if (err) {
console.error(err);
return;
}
if (data === null) {
console.log("No results");
return;
}
var stream = { };
data.forEach(function (streams) {
console.log("Got " + streams.name + " " + streams.streamurl);
stream[streams.name] = streams.streamurl;
// stream += 'name: '+streams.name+'},{streamurl: '+streams.streamurl;
// console.log("stram arry "+stream[streams.name] )
console.log("END OF FIND:"+JSON.stringify(stream))
}, renderme(stream));
// console.log("Result:", votes);
//var myresult = Object.keys(stream).map(function (name) {
// return { name: name, url: stream[name] };
//})
console.log("before return stream "+stream);
return stream;
});
}
function renderme(resa) {
console.log("RESA"+JSON.stringify(resa))
var resa = JSON.stringify(resa);
res.render('dashboard', {
title: 'Dashboard',
user: req.user,
listing: resa
}
)
}
You're passing the result of renderme(stream) as a second argument to forEach(). renderme(stream) is then evaluated immediately before your forEach() callback is called, when stream is still an empty object. My guess is you want something like this:
data.forEach(function (streams) {
console.log("Got " + streams.name + " " + streams.streamurl);
stream[streams.name] = streams.streamurl;
console.log("END OF FIND:"+JSON.stringify(stream))
});
renderme(stream);
Actually i figure that why would i pass the function as i could just do whatever i need to directly in there.
That worked perfectly, thanks for the tip.
data.forEach(function (streams) {
console.log("Got " + streams.name + " " + streams.streamurl);
stream[streams.name] = streams.streamurl;
});
res.render('dashboard', {
title: 'Dashboard',
user: req.user,
listing: data
}
)
I have the following Azure Mobile Services API get function. I want to set the isValidUser flag based on if there is a record for the providerKey (from the twitter authentication) in the SQLMembership table (AspNetUserLogins).
While testing, I see the following in the log file, confirming that the flag is being set.
"setting isValidUser [object Object] Number of records = 1"
However, if(isValidUser) is not getting evaluated correctly. The result I get from the API is "Not a registered user." which is set from the else portion of the if(isValidUser) check.
Why is it that the value set inside the mssql.query() is not available outside of it?
exports.get = function(request, response) {
var authenticatedUserId = request.user.userId;
var providerName = authenticatedUserId.split(":")[0];
var providerUserId = authenticatedUserId.split(":")[1];
var isValidUser = false;
console.log('providerName = ' + providerName.trim());
console.log('providerUserId = ' + providerUserId.trim());
request.service.mssql.query(
"select userId from dbo.AspNetUserLogins where LoginProvider = '" + providerName + "' and ProviderKey = '" + providerUserId + "'",
{
success: function(results)
{
console.log('inside success AspNetUserLogins. ' + results + " Number of records = " + results.length);
if (results.length == 1) {
console.log('setting isValidUser ' + results + " Number of records = " + results.length);
isValidUser = true;
}
},
error : function(err)
{
console.log('inside error AspNetUserLogins. ' + err);
response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
}
}
);
if (isValidUser) {
request.service.mssql.query('select * from dbo.Church',
{
success: function(results)
{
console.log('inside success Church' + results);
response.json(statusCodes.OK, results);
},
error : function(err)
{
console.log('inside error : ' + err);
response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
}
}
);
} else {
response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: "Not a registered user." + isValidUser });
}
response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: "Unexpected end." });
};
The call to mssql.query is an asynchronous function (like many other functions in node.js); when it returns the callback (either the success or the error) hasn't been executed yet, so when you check the isValidUser flag, it still has the original value (false).
What you need to do is to move that code to inside the success callback, and that should work:
exports.get = function(request, response) {
var authenticatedUserId = request.user.userId;
var providerName = authenticatedUserId.split(":")[0];
var providerUserId = authenticatedUserId.split(":")[1];
var isValidUser = false;
console.log('providerName = ' + providerName.trim());
console.log('providerUserId = ' + providerUserId.trim());
var sql = "select userId from dbo.AspNetUserLogins where LoginProvider = ? and ProviderKey = ?";
var sqlParams = [providerName, providerUserId];
request.service.mssql.query(sql, sqlParams, {
success: function(results)
{
console.log('inside success AspNetUserLogins. ' + results + " Number of records = " + results.length);
if (results.length == 1) {
console.log('setting isValidUser ' + results + " Number of records = " + results.length);
isValidUser = true;
}
if (isValidUser) {
request.service.mssql.query('select * from dbo.Church', {
success: function(results)
{
console.log('inside success Church' + results);
response.send(statusCodes.OK, results);
},
error : function(err)
{
console.log('inside error : ' + err);
response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
}
});
} else {
response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: "Not a registered user." + isValidUser });
}
},
error : function(err)
{
console.log('inside error AspNetUserLogins. ' + err);
response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
}
});
};
One more thing: do use parameters in the SQL (also shown above), instead of composing the query directly. In this case (you're using the user id) it shouldn't be a problem, but as a general rule you should use parameters whenever possible to prevent SQL injection attacks.