Browse project docs

Search Example

Run a complete ldapjs-community LDAP search with bind, streamed results, error handling, and cleanup.

On this page

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

bash
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

javascript
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.