This example binds with a service account, searches below a configured base DN, prints selected attributes, and unbinds after the result stream ends.
Link to EnvironmentEnvironment
export LDAP_URL='ldaps://directory.example.com:636'
export LDAP_BIND_DN='uid=service,ou=system,dc=example,dc=com'
export LDAP_PASSWORD='replace-me'
export LDAP_BASE_DN='ou=people,dc=example,dc=com'
export LDAP_CA_FILE='/path/to/directory-ca.pem'
Link to CodeCode
const fs = require('node:fs')
const ldap = require('ldapjs')
const required = ['LDAP_URL', 'LDAP_BIND_DN', 'LDAP_PASSWORD', 'LDAP_BASE_DN', 'LDAP_CA_FILE']
for (const name of required) {
if (!process.env[name]) throw new Error(`Missing ${name}`)
}
const client = ldap.createClient({
url: process.env.LDAP_URL,
connectTimeout: 5000,
timeout: 10000,
tlsOptions: { ca: [fs.readFileSync(process.env.LDAP_CA_FILE)] }
})
let finished = false
function close(exitCode) {
if (finished) return
finished = true
client.unbind(() => {
process.exitCode = exitCode
})
}
client.on('error', (err) => {
console.error('LDAP connection error:', err.message)
close(1)
})
client.bind(process.env.LDAP_BIND_DN, process.env.LDAP_PASSWORD, (bindError) => {
if (bindError) {
console.error('Bind failed:', bindError.message)
close(1)
return
}
const options = {
scope: 'sub',
filter: '(objectClass=person)',
attributes: ['dn', 'cn', 'mail'],
paged: true
}
client.search(process.env.LDAP_BASE_DN, options, (searchError, response) => {
if (searchError) {
console.error('Search could not start:', searchError.message)
close(1)
return
}
response.on('searchEntry', (entry) => console.log(entry.object))
response.on('searchReference', (referral) => console.log('Referral:', referral.uris))
response.on('error', (err) => {
console.error('Search failed:', err.message)
close(1)
})
response.on('end', (result) => {
if (result.status !== 0) {
console.error('LDAP search status:', result.status)
close(1)
return
}
close(0)
})
})
})
Adapt the base DN, filter, selected attributes, paging, and limits to the target directory. Never interpolate untrusted input into a filter string; construct a filter object or escape the value correctly.