Query a real local LDAP directory
LDAP(options, callback) is the native read client. options.ldap supplies host and port; user is the bind DN, password its password, dn the search base, and type the requested object class (person or group). type:'profile' uses login to search sAMAccountName and returns one object or null. noauth:true skips bind; it does not grant directory permissions. Always specify a search base explicitly.
attributes maps returned attribute names to conversion types (string, number, date, buffer, hex, base64, etc.); it is not an allowlist of attributes to retrieve. A directory may return scalar values or arrays when an attribute repeats. Restrict the data your HTTP API exposes.
This executable fixture requires local OpenLDAP tools: slapd, ldapadd and the core/cosine/inetorgperson schema files. On macOS the defaults below use the system tools; other installations can set FORGE_SLAPD, FORGE_LDAPADD and FORGE_LDAP_SCHEMA. It runs a separate unprivileged loopback server and temporary LDIF database, then terminates it. It never uses an existing directory. The test covers search, multiple attribute values and an invalid-bind boundary; it does not certify Active Directory compatibility, TLS/StartTLS, groups or reconnect behavior. Never send real credentials over an unprotected network.
Decide authentication from the bind. Check the result of the bind in your own code, and treat a returned profile as authenticated only after the bind has succeeded.
exports.install = function() {
ROUTE('POST /directory-fixture/ @json', directory);
};
function directory($) {
var port = Number($.body.port);
if (!Number.isInteger(port) || port < 1024 || port > 65535)
return $.invalid(400);
LDAP({
ldap: { host: '127.0.0.1', port: port },
user: 'cn=admin,dc=forge,dc=test',
password: $.body.wrong ? 'incorrect' : 'local-fixture-only',
dn: 'dc=forge,dc=test',
type: 'person',
attributes: { cn: 'string', mail: 'string' }
}, function(err, people) {
if (err)
$.json({ failed: true });
else
$.json({ people: people.map(person => ({ cn: person.cn, mail: person.mail })) });
});
}