From f9128499df2ba336e83de9747809160950da9a83 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 5 Aug 2026 10:19:39 +0000 Subject: [PATCH] Raise LDAP client timeout for the directory-wide import browse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ldapjs's `timeout` option is a single flat deadline for the whole operation (set once when the request is sent, not reset per entry received) — 5s is fine for a bind or a single-match search during login, but the admin "import accounts" browse runs an unbounded (objectClass=person) search across the entire base DN, which can take longer than 5s against a real AD domain and was getting killed mid-stream (surfaced as ldapjs's generic " closed" ConnectionError). Bumped that one call site to 30s; login-path calls keep the tighter 5s deadline. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_012o9j9RezxbZVKQMrB7oRLY --- src/lib/ldap/client.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/lib/ldap/client.ts b/src/lib/ldap/client.ts index 2f30512..c47b362 100644 --- a/src/lib/ldap/client.ts +++ b/src/lib/ldap/client.ts @@ -13,11 +13,16 @@ interface ConnectionSettings { useTls: boolean; } -function createLdapClient(settings: ConnectionSettings): ldap.Client { +function createLdapClient(settings: ConnectionSettings, timeoutMs = 5_000): ldap.Client { const protocol = settings.useTls ? "ldaps" : "ldap"; const client = ldap.createClient({ url: `${protocol}://${settings.host}:${settings.port}`, - timeout: 5_000, + // ldapjs's `timeout` is a single flat deadline for the whole operation + // (set once when the request is sent, not reset per entry received) — + // fine for a bind or a single-match search, but a directory-wide + // "(objectClass=person)" browse over the whole base DN can easily take + // longer than 5s on a real AD domain and gets killed mid-stream. + timeout: timeoutMs, connectTimeout: 5_000, }); // A socket-level error (e.g. host unreachable) with no listener would @@ -120,7 +125,7 @@ export async function searchLdapDirectory(): Promise { const settings = await getLdapSettings(); if (!settings) return []; - const client = createLdapClient(settings); + const client = createLdapClient(settings, 30_000); try { await bind(client, settings.bindDn, settings.bindPassword); const entries = await search(client, settings.baseDn, settings.listFilter);