# Telephone Directory

## Telephone Directory for Active Directory

For those who do not want to read the article, immediately the repository on github .

And the rest under the cat is waiting for an incoherent and meaningless story about how I got to such a life , with the help of node-webkit, I wrote an application that I 've been waiting for a year .
All my life as a system administrator, I admired MS Active Directory. And as soon as such an opportunity appeared - introduced it at the enterprise where I work.

And away we go ... I began to integrate everything I can reach with AD. Authentication of proxies, database of employees for ACS, Antivirus, etc. And I did not have enough for the happiness of a telephone directory, which would take all the data from the AD database. For six months now I have been tormenting Google on this topic, but the results are not comforting.

Basic requirements for such a directory:
1. separate portable application. Every time I stumbled upon a web-based directory, I thought, “If you raise a server for this, then I’ll already make a full-fledged corporate portal, and now I just need a small directory.
2. free
3. The most simple and convenient to use. It always seemed to me just a table with sorting and searching

From the entire zoo of such software that I found, there are several types:
I once saw a server version in php, but I didn’t find it when writing an article. It can be attributed to the 3rd group, since the server requirement for me is a drawback.
Concerning the reference from dmsoft
It looks like this

And there is no way at least to make the column width of the phone larger by default. And setting up the interface every time you start is terribly annoying.

Nothing boded the troubles of solving this problem, but the day before yesterday I found out about node-webkit !

Ability to write a desktop application in a familiar language - what could be better? My joy knew no bounds.
But bad luck ... At home, a small child, constantly requiring attention, and at work, suddenly work. There is no time and place to code categorically.
But fate was favorable to me - on Sunday afternoon the child decided to sleep . The wife, apparently recalling my enthusiastic cries about how node-webkit is cool, and unraveling my secret desires, in response to the question “what do we do while the baby is sleeping?”

### Episode 1: Prototype March

So. I have 1.5 - 2 hours to learn the new technology (even two, since nodejs I also didn’t, in fact) and write software with it that for some reason none of the open source programmers have written yet .

First of all, Google asked about the connection of nodejs with ActiveDirectory. He suggested two modules: node-activedirectory and ldapjs . Understand that by what time was not, so the choice fell on the first.
THE CODE
var ActiveDirectory = require('activedirectory');
var groupName = 'Employees';
if (err) {
console.log('ERROR: ' +JSON.stringify(err));
return;
}
else {
console.log(users);
}
});


var groupName = 'Employees';
EMPLOYEES - a group which includes all current employees
RESULT
ERROR: {"dn":"","code":49,"name":"InvalidCredentialsError","message":"80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db0\u0000"}
hmm ....

An attempt to poke the second module led to the same result, but for a longer time. Mana smoking, kicking of the familiar nodejs nickname and crazy luck did give the result: for some reason, the domain’s superadmin is not authenticated, but the disenfranchised user created for the guest Internet has worked !
HURRAH

There is no time for legal proceedings - we went further.
1. git init
3. dirty hack for debugging
require('nw.gui').Window.get().showDevTools();

4. copy-paste of old code
Voila

You can start doing magic ... But almost an hour has passed. The baby can wake up at any moment. There is no time for magic - we take everything ready.
Quick googling turned out to be an excellent script for working with the TinyTable table . I copy it entirely with an example to myself.
Bit of code
var ad = new ActiveDirectory(credentials.dn, credentials.dc, credentials.user, credentials.pass, {attributes: {user: [ 'cn', 'telephonenumber', 'mail' ]}}); // поменял эту строчку что бы доставало только ФИО телефон и мыло
function users2table (users) {
tablehtml = '';
for (i in users) {
var user = users[i];
console.log(user);
tablehtml+='';
tablehtml+= ''+user.cn+''
tablehtml+= ''+user.telephoneNumber+''
tablehtml+= ''+user.mail+''
tablehtml+=''
}
console.log(tablehtml);
$('#table tbody').html(tablehtml); sorter.init(); }  THERE There was a joyful cry from the crib. ### Episode 2: Morning Coffee At 6:50 , I have about 20 minutes ... 1. We remove the address bar and call the window package.json "window": { "title": "Telephone Directory", "toolbar": false }  2. Autofocus on the search field users2table $('#query').focus();

3. add the department to the table, or rather, we’ll take away not just anything, but only the 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+= ''+user.department+''

4. And open the window to full screen, so as not to bathe about the size
Hidden text
require('nw.gui').Window.get().maximize();

But it’s already 7:30 and I have to run.

### Episode 3: We Drive

During lunch, I returned to the code.
First of all, I added a feature that I was thinking about all the way to work - caching. For every time you wait for a download (albeit just a few seconds) looking at an empty window is annoying.
THE CODE
in the event of receiving a response from ldap changed this:
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));


and also added to empty space in the script a load with localstorage if not empty
if (localStorage.users) users2table(JSON.parse(localStorage.users));


I fixed a couple of bugs, combed it, added mailto links for emails ... Basically everything.
DONE!
Just lunch has ended.
But this functionality already fully covers all my plans, so for now I have stopped.

### Installation

1. put node-webkit
3. put the private.js file
content
module.exports = {
dn:"ldap://example.com"
,dc:"dc=example,dc=com"
,user:"user"
,pass:"pass"
};

4. launch
path\to\nodewebkit\nw.exe path\to\telephone-directory


1. Pack the telephone-directory in .zip
2. Rename the archive to .nw
3. Some magic
copy /b path\to\nodewebkit\nw.exe+path\to\telephone-directory telephone-directory.exe

4. Dock all other files from node-webkit except nw.exe to the directory with telephone-directory.exe

It should turn out like this:

Everything - you can upload it to a network drive or distribute as you please

#### PS

The code was written in a hurry, so it does not shine with beauty. Many things can and should be further developed. But without the help of the community, I’m unlikely to do anything more than what is already there. For what already exists - works and fully meets the requirements - but no more is 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 optimization of the code may be required, but the corp portal is probably already used or something similar.

#### PPPS

The code is 45 lines , so I’m sure that even for system administrators who do not know JS, adjusting the project to your needs will not be difficult.