Migrate ldapjs Bind Code to ldapts

Migrate ldapjs bind code to ldapts by translating connection and authentication APIs, preserving TLS validation, handling errors, and testing failures.

On this page

Link to Why Migrate from ldapjs to ldapts?Why Migrate from ldapjs to ldapts?

Migrating from ldapjs to ldapts is a necessity for any Node.js project that must remain secure, maintainable, and compatible with current Node.js releases. The ldapjs package—once the standard LDAP client for Node—is now archived and unmaintained. This means no security, bug, or compatibility fixes will be released, leaving lingering vulnerabilities and incompatibilities that cannot be resolved.

In contrast, ldapts is an actively developed, fully type-safe LDAP client built for modern JavaScript and TypeScript. It provides strong type checking, robust error reporting, first-class async/await support, and up-to-date TLS and credential management features. For anyone building or maintaining LDAP authentication or directory integration, migrating is not optional—it is required for ongoing security and codebase health.

Link to Comparing Bind Operations: ldapjs vs. ldaptsComparing Bind Operations: ldapjs vs. ldapts

The bind operation is fundamental to LDAP authentication. Migrating it from ldapjs to ldapts requires rethinking function signatures, error handling, parameter handling, and credential lifecycle.

Link to Side-by-Side Bind ExampleSide-by-Side Bind Example

ldapjs simple bind (callback style):

js
const ldap = require('ldapjs');
const client = ldap.createClient({ url: 'ldap://ldap.example.com' });

client.bind('cn=admin,dc=example,dc=com', 'password', function(err) {
  if (err) {
    console.error('Bind failed:', err);
  } else {
    console.log('Bind successful');
  }
});
  • Signature: client.bind(dn, password[, controls], callback)
  • controls is optional.
  • Error is passed to the callback or emitted via client events.

ldapts bind (async/await style):

js
import { Client } from 'ldapts';

const client = new Client({ url: 'ldap://ldap.example.com' });

try {
  await client.bind('cn=admin,dc=example,dc=com', 'password');
  console.log('Bind successful');
} catch (err) {
  console.error('Bind failed:', err);
}
  • Signature: await client.bind(dn, password)
  • No controls argument (ldapts does not accept controls in bind, per API docs).
  • All errors are JavaScript exceptions (Promise rejections), not callback parameters or events.

Link to Key DifferencesKey Differences

  • Asynchronous Model: ldapjs uses callbacks and events; ldapts uses promises and async/await.
  • Controls in bind: ldapjs optionally accepts a controls parameter; ldapts’ bind does not support controls.
  • Error Handling: ldapjs propagates errors via callbacks and client events. ldapts throws exceptions and expects error handling via try/catch.
  • Type Safety: ldapts enforces DN and credential types.
  • Credential Lifetime: ldapts strictly holds credentials for the session only; after unbind(), all credentials are wiped.

Link to Essential Migration Patterns and GotchasEssential Migration Patterns and Gotchas

Link to Error Handling: Event-Based to Promise-BasedError Handling: Event-Based to Promise-Based

ldapjs error event:

js
client.on('error', (err) => {
  console.error('ldapjs client error:', err);
});

ldapts (Promise-based) conversion:

js
try {
  await client.bind(dn, password);
  // use connection
} catch (err) {
  console.error('ldapts error:', err);
}
  • There are no connection or error events in ldapts. All error handling must be performed through try/catch on async operations.
  • Attempting to set up event listeners for errors will not work in ldapts.

Link to Credential and Unbind LogicCredential and Unbind Logic

  • ldapts only keeps the credentials as long as the client is bound.
  • Calling await client.unbind(); purges credentials from memory and invalidates the session—not a soft disconnect.
  • Any operation (like search or modify) after unbind requires a fresh bind.
  • Refactor code that previously treated unbind as a disconnect or ignored its credential implications.

Link to Managing Reconnects and TLS UpgradesManaging Reconnects and TLS Upgrades

  • By default, LDAP bind credentials in ldapts are not automatically restored after a reconnect or a startTLS upgrade.

  • Solution: Use the autoRebind option on the ldapts client to automatically re-bind after reconnects or TLS upgrades:

    js
    const client = new Client({
      url: 'ldap://ldap.example.com',
      autoRebind: true, // enable auto-rebinding of credentials
    });
    
  • If not enabled, you must manually call bind after a disconnect or connection upgrade.

Link to Mapping Other Common PatternsMapping Other Common Patterns

  • Do not copy ldapjs connection or error event listeners to ldapts—they have no effect.
  • Migration is not a line-for-line rewrite; entire error-handling and credential management flows must be re-architected for promises and explicit operation sequencing.

Link to TLS, LDAPS, and SASL: Security in ldaptsTLS, LDAPS, and SASL: Security in ldapts

Link to Secure Client Connection Example (TLS/LDAPS)Secure Client Connection Example (TLS/LDAPS)

ldapts secure client (LDAPS or startTLS):

js
import { Client } from 'ldapts';
import fs from 'fs';

const client = new Client({
  url: 'ldaps://ldap.example.com', // or ldap:// for startTLS
  tlsOptions: {
    ca: [fs.readFileSync('./ca-cert.pem')], // custom CA for server validation
    // You can provide other Node.js TLS options here
  }
});
  • Use the tlsOptions property for client certificate validation and to set up custom trust stores or client certificate authentication.
  • If using startTLS, you must explicitly upgrade the connection via the startTLS operation and rebond as needed.

Link to SASL Mechanisms and Authentication LimitationsSASL Mechanisms and Authentication Limitations

Only PLAIN and EXTERNAL SASL mechanisms are supported in ldapts.
This is explicitly documented, and advanced SASL methods such as GSSAPI (Kerberos) are not supported as of the latest release. Any enterprise flow requiring Kerberos or GSSAPI will not work with ldapts and must use alternative libraries or authentication patterns.

Link to Troubleshooting Common Migration IssuesTroubleshooting Common Migration Issues

Link to Authentication Fails After MigrationAuthentication Fails After Migration

  • Ensure all LDAP client operations are wrapped in try/catch blocks. Uncaught promise rejections can cause application crashes or silent failures.
  • Check that all distinguished names (DN) and passwords are valid strings—ldapts enforces stricter type validation.
  • Verify that unbind() is not called prematurely; once unbound, any new operation requires an explicit bind().

Link to Rebind and Credential PersistenceRebind and Credential Persistence

  • If authentication fails after a reconnect, TLS upgrade, or during intermittent network issues, ensure you are either:
    • Using autoRebind: true on the ldapts client, or
    • Manually calling bind() whenever reconnecting/transferring the connection state.
  • Example of enabling autoRebind:
    js
    const client = new Client({ url: 'ldap://ldap.example.com', autoRebind: true });
    

Link to Refactoring Event-Driven Error LogicRefactoring Event-Driven Error Logic

  • Remove all custom error event listeners. All such event handlers (client.on('error', ...)) must be migrated to promise-based error handling using try/catch.
  • For example, replace:
    js
    client.on('error', (err) => handleError(err));
    
    with:
    js
    try {
      await client.bind(dn, password);
      // Work with connection
    } catch (err) {
      handleError(err);
    }
    
  • Audit for places in the codebase where the bind/authentication error is only handled via events and ensure it's handled in the control flow.

Link to Credential Wiping after UnbindCredential Wiping after Unbind

  • Remember: in ldapts, credentials are immediately scrubbed from memory after unbind(). This is a deliberate security measure and cannot be bypassed.

Link to Next Steps and Further LearningNext Steps and Further Learning

  • Review the ldapts documentation and changelog to stay current with API and feature support, especially for advanced authentication flows and upcoming features.
  • Search the ldapts issue tracker for real-world migration discussions and edge cases.
  • If your authentication code relied on GSSAPI/Kerberos, plan for a different strategy—ldapts will not support these mechanisms as of now.

This migration is not a find/replace or “drop-in” change. It requires understanding the new idioms, credential lifecycles, and safer error handling patterns of ldapts, and carefully mapping your legacy code while refactoring for modern, secure LDAP workflows in Node.js.

Link to SourcesSources