Improve latency of findUsers query made by node js activedirectory module - node.js

I am expriencing high latency when fetching users from active directory in nodejs.
I am using the node library from npm 'activedirectry'. https://www.npmjs.com/package/activedirectory
The amount of users is relatively not big, About 1000 users...
The time of the query takes between 2 to 4 seconds.
The default query provided by the function findUsers of the 'activedirectory' library is (&(|(objectClass=user)(objectClass=person))(!(objectClass=computer))(!(objectClass=group))).
I added an additional filter on the sAMAccountName field. sAMAccountName=*somePartOfName*
In any case, with or without my addition the query time is still slow.
I don't have full configuration of the active directory server,
But it seems like other platforms on the same network work faster with the active directory but they work with other frameworks, in java and .NET.
What could be the reason for this high latency?
Thanks
// ad is configured only with user, password, base dn and url
function findUsers(partOfsAMAccountName) {
const additionalQuery = `sAMAccountName=*${partOfsAMAccountName}*`;
return new Promise(resolve => {
ad.findUsers(additionalQuery, false, (error, users) => {
if(error) {
console.error('%j', error);
}
resolve(users || []);
})
}
}
What I am tring to do is to create an autocomplete mechanism based on the usernames of the active directory.
On the same network we have bitbucket server connected to the same active directory server. It seems like from the bitbucket client the autocomplete is much faster. about 1 sec from the client side.
I had already searched for the open souce of bitbucket but didn't find any.

I have no idea about node.js, and have never programmed in the same. But, from the question I feel that default query provided for findUsers() might be the culprit.
As per Microsoft Docs, LDAP filter for
(&(objectClass=user)(objectCategory=person))
is sufficient for determining the users.
In the official documentation for function findUsers(opts, callback), I can see the argument opts description about Optional parameters to extend or override functionality.
So, I think you can override the LDAP filter query using the opts argument in findUsers function to keep the above advised LDAP filter, and additionally put your sAMAccountName condition in the search query. Please explore on how to override the opts argument, as I can't help you with that.
I am hopeful that the result would be comparatively faster after doing the search this way.

Related

Getting 'Could not find stored procedure' error calling SQL Server stored procedure in Node JS from AWS RDS database

We always normally work in Azure where I write around 200 stored procedures a year in their SQL Server database.
We had to create a SQL Server database in AWS-RDS and still call it in our Node APIs like usual. I was able to quickly and easily set up the AWS DB in SQL Server Management Studio so I do know the credentials.
I created several tables and several stored procedures with no problems and tested to make sure they worked there. When I called them like I normally do in Node, I found I was getting an error
Could not find stored procedure
I went through forums all over but most of the data pertains to MySQL instead of SQL Server, and after trying everything I saw in the forums have not been able to complete what should be a very simple process. I would imagine there is some simple thing I missed, but after 2 days it is time for some fresh ideas.
I am setting up the credentials like this:
var awsConnection = {
host : process.env.RDS_HOSTNAME,
user : process.env.RDS_USERNAME,
password : process.env.RDS_PASSWORD,
port : process.env.RDS_PORT
};
I am using the endpoint provided by AWS for the host, the username and password I use to login to SQL Server Management Tool (which works). The port number is the one specified by AWS (1433 - the default for SQL Server).
I call it in my api like this:
await sql.connect(connectionAWS).then(pool => {
// Stored procedure
console.log("awsConnection INSIDE: " + JSON.stringify(awsConnection));
return pool.request()
.input('repId', sql.VARCHAR(40), repObj.RepID)
.execute('UserExistsBD');
}).then(async result => { ...
I added the console.log to see if we were getting past the login and it appears that we do. I also used Telnet to make sure the endpoint/port combo work and they do. I also checked AWS to make sure the Subnets, Route tables, and gateways were good and to make sure my IP Address was white listed. Any ideas would be very much appreciated!

Can a Node package require a DB connection?

As per the title, can a Node.js package require a database connection?
For example, I have written a specific piece of middlware functionality that I plan to publish via NPM, however, it requires a connection to a NoSQL database. The functionality in its current state uses Mongoose to save data in a specific format and returns a boolean value.
Is this considered bad practice?
It is not a bad practice as long as you require the DB needed and also explicitly state it clearly in your Readme.md file, it's only a bad practice when you go ahead and work without provide a comment in your codes or a readme.md file that will guide any other person going through your codes.
Example:
//require your NoSQL database eg MongoDB
const mongoose = require('mongoose');
// to connect to the database. **boy** is the database name
mongoose.connect('mongodb://localhost/boy', function(err) {
if (err) {
console.log(err);
} else {
console.log("Success");
}
});
You generally have two choices when your module needs a database and wants to remain as independently useful as possible:
You can load a preferred database in your code and use it.
You can provide the developer using your module a means of passing in a database that meets your specification to be used by your module. The usual way of passing in the database would be for the developer using your module to pass your module the data in a module constructor function.
In the first case, you may need to allow the developer to specify a disk store path to be used. In the second case, you have to be very specific in your documentation about what kind of database interface is required.
There's also a hybrid option where you offer the developer the option of configuring and passing you a database, but if not provided, then you load your own.
The functionality in its current state uses Mongoose to save data in a specific format and returns a boolean value. Is this considered bad practice?
No, it's not a bad practice. This would be an implementation of option number 1 above. As long as your customers (the developers using your module) don't mind you loading and using Mongoose, then this is perfectly fine.

Feathers JS nested Routing or creating alternate services

The project I'm working on uses the feathers JS framework server side. Many of the services have hooks (or middleware) that make other calls and attach data before sending back to the client. If I have a new feature that needs to query a database but for a only few specific things I'm thinking I don't want to use the already built out "find" method for this database query as that "find" method has many other unneeded hooks and calls to other databases to get data I do not need for this new query on my feature.
My two solutions so far:
I could use the standard "find" query and just write if statements in all hooks that check for a specific string parameter that can be passed in on client side so these hooks are deactivated on this specific call but that seems tedious especially if I find this need for several other different services that have already been built out.
I initialize a second service below my main service so if my main service is:
app.use('/comments', new JHService(options));
right underneath I write:
app.use('/comments/allParticipants', new JHService(options));
And then attach a whole new set of hooks for that service. Basically it's a whole new service with the only relation to the origin in that the first part of it's name is 'comments' Since I'm new to feathers I'm not sure if that is a performant or optimal solution.
Is there a better solution then those options? or is option 1 or option 2 the most correct way to solve my current issue?
You can always wrap the population hooks into a conditional hook:
const hooks = require('feathers-hooks-common');
app.service('myservice').after({
create: hooks.iff(hook => hook.params.populate !== false, populateEntries)
});
Now population will only run if params.populate is not false.

MongoDB + node: not authorized to execute command (sometimes works, sometimes doesn't)

I'm facing a problem with my MongoDB environment - the setup is as follows:
My node app provides a restify API which handles user registration (look up if a user exists in a collection based on his mail, and if not, insert him (note - insert uses bcrypt to hash the passwords, so probably is a bit slower)). It uses restify and Mongoose ORM.
A second benchmark script (also written in node, running on the same machine) accesses this restify API using HTTP PUT.
I'm starting around 20-30 of these requests in the benchmark (with random data) and only some of the API requests correctly insert the new users. For the other, MongoDB produces errors similar to the following:
not authorized on ... to execute command { find: "users", filter: { mail: "rroouksl#hddngrau.de" } }
not authorized on ... to execute command { insert: "users", documents: [ { ... } ], ordered: false, writeConcern: { w: 1 } }
Some other users get inserted perfectly fine. Especially with a low number of requests at the same time (1-5) no problems occur. Shouldn't Mongo be able to handle these "low" amount of requests? Is it a problem because it's running on the same machine? Hasn't the user I created in Mongo for this project got enough txns/second allowed?
Best regards,
Zahlii
It turned out that mongo was still using the "old" storage engine and not WiredTiger. Since my queries included updating records, the old engine performed collection-based locks which means that the errors were solely based on read-write locks.
I migrated to WiredTiger which performs document-based locking and since then, the database handles many parallel requests without these errors (although sometimes under heavy load they appear again - but this is part of mongo being NoSQL I guess)
You can try:
Db.authenticate(user, password, function(err, res) {
// callback
});
Also see the source.

Node.js: Connect-Auth VS. EveryAuth

Can anyone give a good comparison between:
https://github.com/ciaranj/connect-auth
and https://github.com/bnoguchi/everyauth
Which seem to be the only options for express/connect
I'm the author of everyauth.
I wrote everyauth because I found using connect-auth lacking in terms of:
Easy and powerful configuration
To get particular, one area where it was lacking in terms of configurability was setting facebook's "scope" security settings dynamically.
Good debugging support
I found connect-auth not-so-straightforward to debug in terms of pinpointing the part of the auth process was failing. This is mostly due to the way that connect-auth sets up its nested callbacks.
With everyauth, I tried to create a system that solved the issues I ran into with connect-auth.
On configuration - every everyauth auth module is defined as a series of steps and configurable parameters. As a result, you have surgery-like precision over what parameters (e.g., hostname, callback url, etc.) or steps (e.g., getAccessToken, addToSession) you want altered. With connect-auth, if you want to change one thing besides the few built in configurable parameters each auth strategy provides, you have to re-write the entire this.authenticate function that defines the logic for all of that strategy. In other words, it has less precision of configurability than everyauth. In other cases, you cannot use connect-auth, as is -- for example, achieving dynamic facebook "scope" configurability - i.e., asking users for more facebook permissions progressively as they get to portions of your app that require more permissions.
In addition to configurable steps and parameters, you can also take advantage of everyauth's auth module inheritance. All modules inherit prototypically from the everymodule auth module. All OAuth2-based modules inherit from the oauth2 module. Let's say you want all oauth2 modules to behave differently. All you need to do is modify the oauth2 auth module, and all oauth2-based modules will inherit that new behavior from it.
On debugging - everyauth, in my opinion, has better debugging visibility because of the very fact that it segments each module explicitly into the steps of which it is composed. By setting
everyauth.debug = true;
you get output of what steps in the authentication process have completed and which ones have failed. You also have granular control over how long each step in each auth strategy has before it times out.
On extensibility - I designed everyauth to maximize code re-use. As mentioned before, all modules inherit prototypically from the everymodule auth module. This means that you can achieve very modular systems while at the same time having fine grained control in terms of over-riding a specific step from an ancestor module. To see how easy it is to extend everyauth with your own auth module, just take a look at any of the specific auth modules in everyauth's source.
On readability - I find everyauth source easier to read in terms of what is going on. With connect-auth, I found myself jumping around the several files to understand under what contexts (i.e., during what steps, in everyauth parlance) each nested callback configured by a strategy was running. With everyauth, you know exactly what piece of logic is associated with which context (aka step). For instance, here is the code describing what happens when an oauth2 provider redirects back to your service:
.get('callbackPath',
'the callback path that the 3rd party OAuth provider redirects to after an OAuth authorization result - e.g., "/auth/facebook/callback"')
.step('getCode')
.description('retrieves a verifier code from the url query')
.accepts('req res')
.promises('code')
.canBreakTo('authCallbackErrorSteps')
.step('getAccessToken')
.accepts('code')
.promises('accessToken extra')
.step('fetchOAuthUser')
.accepts('accessToken')
.promises('oauthUser')
.step('getSession')
.accepts('req')
.promises('session')
.step('findOrCreateUser')
.accepts('session accessToken extra oauthUser')
.promises('user')
.step('compile')
.accepts('accessToken extra oauthUser user')
.promises('auth')
.step('addToSession')
.accepts('session auth')
.promises(null)
.step('sendResponse')
.accepts('res')
.promises(null)
Without needing to explain how this works, its pretty straightforward to see what an oauth2 strategy does. Want to know what getCode does? The source again is very straightforward:
.getCode( function (req, res) {
var parsedUrl = url.parse(req.url, true);
if (this._authCallbackDidErr(req)) {
return this.breakTo('authCallbackErrorSteps', req, res);
}
return parsedUrl.query && parsedUrl.query.code;
})
Compare this all to connect-auth's facebook code, which for me at least, took more time than I thought it should have to figure out what is getting executed when. This is mostly because of the way in which the code is spread across files and because of the use of a single authenticate method and nested callbacks to define authentication logic (everyauth uses promises to break down the logic into easily digestible steps):
that.authenticate= function(request, response, callback) {
//todo: makw the call timeout ....
var parsedUrl= url.parse(request.url, true);
var self= this;
if( parsedUrl.query && parsedUrl.query.code ) {
my._oAuth.getOAuthAccessToken(parsedUrl.query && parsedUrl.query.code ,
{redirect_uri: my._redirectUri}, function( error, access_token, refresh_token ){
if( error ) callback(error)
else {
request.session["access_token"]= access_token;
if( refresh_token ) request.session["refresh_token"]= refresh_token;
my._oAuth.getProtectedResource("https://graph.facebook.com/me", request.session["access_token"], function (error, data, response) {
if( error ) {
self.fail(callback);
}else {
self.success(JSON.parse(data), callback)
}
})
}
});
}
else {
request.session['facebook_redirect_url']= request.url;
var redirectUrl= my._oAuth.getAuthorizeUrl({redirect_uri : my._redirectUri, scope: my.scope })
self.redirect(response, redirectUrl, callback);
}
}
A few other differences:
everyauth supports traditional password-based authentication. connect-auth, as of this writing, does not.
The foursquare and google support in connect-auth is based on the older OAuth1.a spec. everyauth's foursquare and google modules are based on their implementations of the newer OAuth2 spec.
OpenId support in everyauth.
everyauth's documentation is much more comprehensive than connect-auth's.
Finally, to comment on Nathan's answer which was unsure about everyauth support for multiple providers at the same time, everyauth does support multiple, concurrent providers. The README on everyauth's github page provides instructions about how to use everyauth to achieve this.
To conclude, I think choice of libraries depends on the developer. I, and others, find everyauth more powerful from their point of view. As Nathan's answer illustrates, yet others find connect-auth more tuned in to their preferences. Whatever your choice, I hope this write-up about why I wrote everyauth helps you in your decision.
Both libraries are pretty close in feature sets, especially in terms of supported providers. connect-auth provides support out-of-the-box to make your own oAuth providers, so that could well help you out if you’re going to need that sort of thing.
The main thing I’ve noted between the two is that I find connect-auth much cleaner with the way it creates and accepts the middleware; you only have to look at the amount of pre-configuration required for the middleware in everyauth to see that it's going to get messy.
Another thing that isn't clear is whether everyauth supports multiple providers at the same time; with connect-auth, it seems possible/more straightforward, though I’ve yet to try this myself.
Thought I'd mention that there is now a new player in the town called PassportJS which features a lot of the same benefits as everyauth however authentication providers are provided by npm modules - so optin in rather than include everything.
I spent a morning playing with everyauth and mongoose-auth to find the examples were broke and they were dead projects. Here are the commit histories:
https:// github.com/jaredhanson/passport/commits/master - June 5th (it's June 18th)
https:// github.com/ciaranj/connect-auth/commits/master - April 18th (2 months ago)
https:// github.com/bnoguchi/mongoose-auth/commits/master - Feb 2012
Here's a google Trends of everyauth, connect-auth, and passportjs
http://www.google.com/trends/explore?q=passportjs%2C+connect-auth%2C+everyauth#q=passportjs%2C%20connect-auth%2C%20everyauth&cmpt=q
My experience with each:
everyauth is far more configurable. For example, I wish to handle my own sessions. With everyauth, with its modularity and introspection, a straightforward task. On the other hand have found everyauth filled with minor bugs and incomplete and/or incorrect documentation. For me, each authentication strategy has required its own understanding and troubleshooting.
passport might be a good bet if you're doing everything "by the book". But any deviation could make life very difficult very quickly, making it, for me, a non-starter.

Resources