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?”

    Answered “okay ... go already program”

    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.
    var ActiveDirectory = require('activedirectory');
    var ad = new ActiveDirectory('ldap://', 'dc=example,dc=com', 'superadmin', 'pass');
    var groupName = 'Employees';
    ad.getUsersForGroup(groupName, function(err, users) {
      if (err) {
        console.log('ERROR: ' +JSON.stringify(err));
      if (! users) console.log('Group: ' + groupName + ' not found.');
      else {

    By the way about
    var groupName = 'Employees';
    EMPLOYEES - a group which includes all current employees
    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 !

    There is no time for legal proceedings - we went further.
    1. git init
    2. License
    3. dirty hack for debugging
    4. copy-paste of old code

    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];
        tablehtml+= ''''
        tablehtml+= ''+user.telephoneNumber+''
        tablehtml+= ''+user.mail+''
      $('#table tbody').html(tablehtml);
    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
      "window": {
        "title": "Telephone Directory",
        "toolbar": false
    2. Autofocus on the search field
    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
    Already quite good
    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.
    in the event of receiving a response from ldap changed this:
    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')};

    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.
    Just lunch has ended.
    But this functionality already fully covers all my plans, so for now I have stopped.


    1. put node-webkit
    2. download release
    3. put the private.js file
      module.exports = {
    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


    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.


    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.


    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.

    Also popular now: