Making Active Directory jQuery-easy.
AD is a Javascript library cloned from https://github.com/kalebo/ad. It implements common Active Directory (AD) tasks built to be as simple as possible. Really simple. The original unmodified package is available @ https://www.npmjs.com/package/ad
The original AD package is great but supports only below 6 AD User Options: userName: String (required) pass: String (required) commonName: String (required) firstName: String lastName: String email: String title: String location: String This code is modified to support So, the original AD package is extended to support other AD attributes.
You can use async
/ await
:
(async () => {
try {
await ad.user().add({
userName: 'jsmith'
firstName: 'John',
lastName: 'Smith',
location: '/Users/Sales',
password: 'J@vascr!pt1'
});
await ad.group().add('Sales');
await ad.user('jsmith').addToGroup('Sales');
} catch(err) {
// ...
}
})();
Or stick with promises:
ad.user('agnes').changePassword('d0ntForgetThisTime')\
.then(() => ad.user('crook').disable())
.then(() => ad.user('larry').move('Dungeon'))
.catch((err) => {
// ...
});
- Robust
user
,group
andou
manipulation methods - High and low-level search methods
- Caching by default
- Fancy result filtering including column and value filtering, sorting and pagination
- Companion drop-in REST API
First, install the library:
npm i ad
yarn add ad
Then add this to index.js
:
const AD = require('ad');
// Your AD account should be a member
// of the Administrators group.
const ad = new AD({
url: "ldaps://127.0.0.1",
user: "[email protected]",
pass: "howinsecure"
});
ad.user().get().then(users => {
console.log('Your users:', users);
}).catch(err => {
console.log('Error getting users:', err);
});
Now run the file:
node index.js
And you're off to the races.
ad.user().get(filter)
ad.user().add(options, stopManipulation=false)
ad.user(username).update(options, stopManipulation=false)
ad.user(username).get(filter)
ad.user(userName).exists()
ad.user(userName).addToGroup(groupName)
ad.user(userName).removeFromGroup(groupName)
ad.user(userName).isMemberOf(groupName)
ad.user(userName).authenticate(password)
ad.user(userName).password(password)
ad.user(userName).passwordNeverExpires()
ad.user(userName).passwordExpires()
ad.user(userName).enable()
ad.user(userName).disable()
ad.user(userName).move(location)
ad.user(userName).unlock()
ad.user(userName).remove()
ad.user(userName).location()
ad.group().get(filter)
ad.group().add(options)
ad.group(groupName).get(filter)
ad.group(groupName).exists()
ad.group(groupName).members()
ad.group(groupName).addUser(userName)
ad.group(groupName).addUser(subGroupName)
ad.group(groupName).removeUser(userName)
ad.group(groupName).remove()
ad.ou().get(filter)
ad.ou().add(options)
ad.ou(ouName).get()
ad.ou(ouName).exists()
ad.ou(ouName).remove()
ad.other().get(filter)
ad.all().get(filter)
ad.find(searchString)
ad.cache(boolean)
ad.cacheTimeout(millis)
Returns all user objects.
await ad.user().get({fields: 'sAMAccountName'});
// => ['jsmith', 'dthree', 'qix'];
Creates a new user. Returns the created user object.
userName
: String (required)pass
: String (required)commonName
: String (required)firstName
: StringlastName
: Stringemail
: Stringtitle
: Stringlocation
: String
If not specified, the first and last name will be based on the commonName
.
But if "stopManipulation=true", the above manipulation is not done.
await ad.user().add({
userName: 'jsmith'
commonName: 'John Smith',
password: 'J@vascr!pt1'
});
// => {sAMAccountName: 'jsmith' ... }
Returns a user object. If no user is matched, returns undefined
.
await ad.user('jsmith').get();
// => {sAMAccountName: 'jsmith', email: '[email protected]' ... }
Returns a Boolean
of whether the user account matched.
await ad.user('lochness').exists();
// => false
Adds a user to a security group.
await ad.user('jsmith').addToGroup('Sales');
// => {success: true}
Removes a user from a security group.
await ad.user('jsmith').removeFromGroup('Sales');
// => {success: true}
Returns a Boolean
based on whether the user is a member of a group.
await ad.user('jsmith').isMemberOf('Sales');
// => true
Attempts to authenticate a user with a given password. Returns Boolean
.
await ad.user('jsmith').authenticate('J@vascript1#!');
// => true
Sets a user's password.
await ad.user('jsmith').password('Wh-m@ksp@ssw-rdslIkethis');
// => true
Sets a user's to never expire.
await ad.user('jsmith').passwordNeverExpires();
// => {success: true}
Unchecks the "Password never expires" box.
await ad.user('jsmith').passwordExpires();
// => {success: true}
Enables a user.
await ad.user('jsmith').enable();
// => {success: true}
Disables a user.
await ad.user('jsmith').disable();
// => {success: true}
Unlocks a user who has been locked out by repeated failed login attempts.
await ad.user('jsmith').unlock();
// => {success: true}
Just kidding. You can't lock an account. Try disabling it instead.
await ad.user('jsmith').disable();
// => {success: true}
Moves a user to another directory, starting from the root of the domain.
await ad.user('jsmith').move('Users/HR');
// => {success: true}
This is the equivalent of acme.co => Users (OU) => HR (OU)
. The new Distinguished Name
(DN) would become CN=John Smith,OU=HR,OU=Users,DC=acme,DC=co
.
To specify a folder that is not an Organizational Unit, prefix it with !
:
await ad.user('admin').move('!Builtin');
// => {success: true}
Returns a user's relative location, separated by /
es.
await ad.user('jsmith').location();
// => 'Users/HR'
Deletes a user. Are you sure you want to do this?
await ad.user('jsmith').remove();
// => {success: true}
Returns all group objects.
await ad.group().get();
// => [{ ... }, { ... }];
Creates a new group. Returns the created group object.
name
: String (required)location
: Stringdescription
: String
await ad.group().add({
name: 'HR'
location: '!Builtin',
description: 'Human Resources users.'
});
// => {sAMAccountName: 'HR' ... }
Returns a group object. If no group is matched, returns undefined
.
await ad.group('HR').get();
// => {sAMAccountName: 'HR', description: 'Human...' ... }
Returns a Boolean
of whether the group account matched.
await ad.group('Beastie Boys').exists();
// => false
Returns a Array
of the group members.
await ad.group('HR').members();
// => [{sAMAccountName: 'hrchief', mail: '[email protected]', ...} ... ]
Adds a user to a group.
await ad.group('HR').addUser('bjones');
// => {success: true}
Adds a subGroup to a group.
await ad.group('HR').addGroup('Recruiting');
// => {success: true}
Removes a user from a group.
await ad.group('HR').removeUser('bjones');
// => {success: true}
Deletes a group.
await ad.group('HR').remove();
// => {success: true}
Returns all ou objects.
await ad.ou().get();
// => [{ ... }, { ... }];
Creates a new Organizational Unit. Returns the created OU object.
name
: String (required)location
: Stringdescription
: String
await ad.ou().add({
name: 'Sales'
location: 'Users'
description: 'Sales Users.'
});
// => {ou: 'Sales' ... }
Returns an OU object. If no OU is matched, returns undefined
.
await ad.ou('Sales').get();
// => {ou: 'Sales', description: 'Sales...' ... }
Returns a Boolean
of whether the OU exists.
await ad.ou('Sales').exists();
// => true
Deletes an Organizational Unit. As a note, if it has any children, this will not work.
await ad.ou('Sales').remove();
// => {success: true}
Returns all objects that are not users or groups.
await ad.other().get();
// => [{ ... }, { ... }];
Returns all objects in the Active Directory instance, grouping by users
, groups
and other
.
await ad.other().get();
// => [users: [...], groups: [...], other: [...]];
Returns a raw search of the entire Active Directory.
await ad.search('CN=Da*');
// => [{...}, {...}];
Enables or disables caching. Defaults to true
.
ad.cache(false);
Sets the amount of milliseconds before a cached item expires. Defaults to ten minutes. Chainable to ad.cache
.
ad.cache(true).cacheTimeout(60000);
Active Directory / LDAP can be hard. Some of us are stuck with it.
Should you really have to know that cn
stands for Common Name
(or was it Canonical
) in order to use it? Or that sn
is a surname
*? I dislike systems that require detailed knowledge of their dirty laundry to do anything with them.
So this was a selfish project, really.
Made with <3 by dthree.
*last name
MIT