Phone Directory for Active Directory

For those who do not want to read the article, immediately repository on
github .
And the rest under the cut is waiting for an incoherent and meaningless story about how I
came to such a life , with the help of node-webkit, wrote the application that
I waited for the year .
Throughout my
adult life as a sysadmin career, I have admired MS's Active Directory. And as soon as such an opportunity appeared, I implemented it at the enterprise where I work.
')
And it started ... I began to integrate everything I reach, with AD. Proxy authentication, employee database for ACS, Anti-Virus, etc. And I did not have enough for the happiness of a
telephone directory that would take all the data from the database AD. Already half a year I now and again torment Google on this topic, but the results are not comforting.
Basic requirements for such a directory:
- separate portable application. Every time I bumped into a web-based directory I thought, “if I’ve already raised a server for this, I’ll make a full-fledged corporate portal there, and now I need only a small directory.
- free
- The simplest and most convenient to use. He always seemed to me just a table with sorting and searching
From the entire zoo of this software that I discovered, there are several types:
I saw once again a server version in php, although I did not find it when writing an article. It can be attributed to the 3rd group, as the server requirement for me is a disadvantage.Regarding the reference from dmsoftHe looks like this

And there is no way at least to make the phone more column wide by default. And to customize the interface every time you start is terribly annoying.
Nothing foreshadowed
troubles solving this problem, but the day before yesterday I found out about
node-webkit !

The ability to write a desktop application in a familiar language - what could be better? My joy knew no bounds.
But here's the bad luck ... At home, a small child, constantly demanding attention, and at work
suddenly work. Coding categorically once and nowhere.
But fate was favorable to me - the child
decided to sleep on Sunday afternoon. My wife, apparently remembering my enthusiastic cries about how cool the node-webkit is, and having solved my secret desires, in response to the question “what do we do while the child sleeps?”

replied "okay ... go program already"
Episode 1: March to the prototype
So. I have 1.5 - 2 hours to master the new technology
(even two, since I also did not know the nodejs) and write with its help software that for some reason none of the programmers have yet written .
First of all, I asked Google about the connection of nodejs with ActiveDirectory. He prompted two modules:
node-activedirectory and
ldapjs . Understand that what time was not, so the choice fell on the first.
CODEvar ActiveDirectory = require('activedirectory'); var ad = new ActiveDirectory('ldap://example.com', 'dc=example,dc=com', 'superadmin', 'pass'); var groupName = 'Employees'; ad.getUsersForGroup(groupName, function(err, users) { if (err) { console.log('ERROR: ' +JSON.stringify(err)); return; } if (! users) console.log('Group: ' + groupName + ' not found.'); else { console.log(users); } });
By the way about
var groupName = 'Employees';
EMPLOYEES - a group that includes all current employees
RESULT ERROR: {"dn":"","code":49,"name":"InvalidCredentialsError","message":"80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db0\u0000"}
well ....
Attempting to poke the second module led to the same result, but for more time. Mana smoking, kicking the familiar nodejs nickname and crazy luck still gave the result: for some reason, the superradmin domain is not authenticated, but the powerless juzverev created for the sake of the guest Internet has
worked !
HOORAY

There is no time for the proceedings with the rights - we drove on.
- git init
- License
- dirty debugging hack
require('nw.gui').Window.get().showDevTools();
- copy-paste old code
Voila

You can start creating magic ... But it's been almost an hour. A child can wake up at any moment. There is no time for magic - we take everything ready.
Fast googling gave a great script to work with the
TinyTable table. I copy it all with an example to me.
A little bit of code var ad = new ActiveDirectory(credentials.dn, credentials.dc, credentials.user, credentials.pass, {attributes: {user: [ 'cn', 'telephonenumber', 'mail' ]}});
Tadam

From the crib came the joyful cry.
Episode 2: Morning Coffee
At
6:50 am, I have about 20 minutes ...
- We remove the address bar and call the window
package.json "window": { "title": "Telephone Directory", "toolbar": false }
- Autofocus on the search field
- we add a department to the table, or rather, we pick up not just anything, but only the full name, phone, email, department
Hidden text var ad = new ActiveDirectory(credentials.dn, credentials.dc, credentials.user, credentials.pass, {attributes: {user: [ 'cn', 'telephonenumber', 'mail', 'department']}});
tablehtml+= '<td>'+user.department+'</td>'
- And open the window to full screen, so as not to sweat about the size
Hidden text require('nw.gui').Window.get().maximize();
Already very well

But already
half past
seven and I have to run.
Episode 3: Directing the mafet
During lunch, I returned to the code again.
First of all, I added a feature that I was considering all the way to work - caching. For each time, waiting for the download (even if only a few seconds) looking at the empty window is annoying.
CODEin the event of receiving a response from ldap changed it:
users2table(users);
on this:
var localusers = localStorage.users; var ldapusers = JSON.stringify(users); if (localusers != ldapusers) {localStorage.users = JSON.stringify(users)} else {console.log('users didn\'t changed')}; users2table(JSON.parse(localStorage.users));
as well as added to an empty space in the script loading from localstorage if not empty
if (localStorage.users) users2table(JSON.parse(localStorage.users));
Fixed a couple of bugs, combed, added
mailto links for emails ... In principle, everything.
READY!

Just lunch is over.
But this functionality already fully covers all my plans, so I stopped at this point for now.
Installation
- put node-webkit
- download release
- place the file private.js
content module.exports = { dn:"ldap://example.com" ,dc:"dc=example,dc=com" ,user:"user" ,pass:"pass" };
- run
path\to\nodewebkit\nw.exe path\to\telephone-directory
Spread
- Pack the telephone-directory in .zip
- Rename the archive to .nw
- Little magic
copy /b path\to\nodewebkit\nw.exe+path\to\telephone-directory telephone-directory.exe
- Exit all other files from node-webkit except nw.exe to the directory with telephone-directory.exe
It should turn out like this:

All - you can upload to a network drive or distribute as you like
PS
The code was written in a hurry, so it does not shine with beauty. Many things can and should be improved. But without the help of the community, I can hardly do anything more than what is already there. For what already is - works and fully satisfies the requirements - and more is not needed.
Pps
The application is designed for an office with about 100 employees
(like the one in which I work) . With less, AD is hardly used. And with more, some kind of code optimization may be required, but the building portal or something like that is probably already used.
PPPS
The code is 45 lines , so I am sure that even for system administrators who do not know JS, fitting the project to fit their needs is not difficult.