UNPKG

ldap-async

Version:

A wrapper around ldapts to provide pooling, config by environment, and other conveniences.

168 lines (167 loc) 7.58 kB
import { Attribute, Client, type ClientOptions, type SearchOptions, type AttributeOptions, type Control, type Entry } from 'ldapts'; import { Readable } from 'node:stream'; type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>; interface StreamIterator<T> { [Symbol.asyncIterator]: () => StreamIterator<T>; next: () => Promise<{ done?: false; value: T; }>; return: () => Promise<{ done: true; value: T; }>; } interface GenericReadable<T> extends Readable { [Symbol.asyncIterator]: () => StreamIterator<T>; } export interface LdapConfig extends Optional<ClientOptions, 'url'> { host?: string; port?: string | number; secure?: boolean; poolSize?: number; startTLSCert?: string | Buffer | boolean; logger?: { debug: (...args: string[]) => void; info: (...args: string[]) => void; warn: (...args: string[]) => void; error: (...args: string[]) => void; }; preserveAttributeCase?: boolean; } export interface LdapChange { operation: string; modification: AttributeOptions | Attribute; } type ValidAttributeInput = boolean | number | string | Buffer; export declare function batch<T = any>(input: T[], batchLimit?: number): T[][]; export default class Ldap { protected connectpromise?: Promise<void>; protected config: ClientOptions; protected clients: (Client & { busy?: boolean; })[]; protected poolSize: number; protected preserveAttributeCase: boolean; protected bindDN: string; protected bindCredentials: string; protected startTLSCert?: string | Buffer | boolean; protected poolQueue: ((client: Client & { busy?: boolean; }) => void)[]; protected closeRequest?: (value?: any) => void; private console; constructor(config?: LdapConfig); protected connect(): Promise<Client & { busy?: boolean; }>; protected bindConnection(client: Client & { busy?: boolean; }): Promise<Client & { busy?: boolean; }>; protected getClient(): Promise<Client & { busy?: boolean; }>; protected release(client: Client & { busy?: boolean; }): void; close(): Promise<void>; wait(): Promise<void>; get<T = any>(base: string, options?: SearchOptions, controls?: Control | Control[]): Promise<LdapEntry<T>>; protected loadPairs: Map<string, Set<string>>; protected loadPromises: Record<string, Promise<Map<string, LdapEntry>> | undefined>; load(dn: string, attributes?: SearchOptions['attributes']): Promise<LdapEntry<any> | undefined>; search<T = any>(base: string, options?: SearchOptions, controls?: Control | Control[]): Promise<LdapEntry<T>[]>; stream<T = any>(base: string, options?: SearchOptions, controls?: Control | Array<Control>): GenericReadable<LdapEntry<T>>; protected useClient<T>(callback: (client: Client) => Promise<T>): Promise<T>; /** * Raw access to the modify LDAP functionality. Consider setAttribute, pushAttribute, * or pullAttribute instead, or addMember/removeMember to manage group memberships. These * methods add extra convenience. */ modify(dn: string, operationOrChanges: string | LdapChange[], modification?: AttributeOptions): Promise<boolean>; /** * Add an object into the system. */ add(newDn: string, entry: any): Promise<boolean>; /** * Remove an object from the system. */ remove(dn: string): Promise<boolean>; /** * Rename an object. */ modifyDN(oldDn: string, newDn: string): Promise<boolean>; /** * Use this method to completely replace an attribute. If you use it on an array attribute, * any existing values will be lost. */ setAttribute(dn: string, attribute: string, val: ValidAttributeInput | ValidAttributeInput[] | undefined): Promise<boolean>; /** * Use this method to completely replace multiple attributes. If any of the given attributes * are array attributes, any existing values will be lost. * * If you need to mix set and push operations, you can do multiple round trips or you can send * multiple operations to the `modify` method. */ setAttributes(dn: string, modification: Record<string, ValidAttributeInput | ValidAttributeInput[] | undefined>): Promise<boolean>; /** * Use this method to add more values to an array attribute without removing any existing values. Any * values that already exist will be ignored (if you used a raw 'modify' operation, you'd get an error). */ pushAttribute(dn: string, attribute: string, valueOrValues: string | string[]): Promise<boolean>; /** * Use this method to remove the specified values from an array attribute while leaving any other * values in place. Any values that don't already exist will be ignored (if you used a raw 'modify' * operation, you'd get an error). */ pullAttribute(dn: string, attribute: string, valueOrValues: string | string[]): Promise<boolean>; removeAttribute(dn: string, attribute: string): Promise<boolean>; /** * Use this method to add a member to a group. memberdn can be an array. each memberdn can be a group or a person. * Any memberdn entries that are already members will be ignored. */ addMember(memberdn: string | string[], groupdn: string): Promise<boolean>; /** * Use this method to remove a member from a group. memberdn can be an array. each memberdn can be a group or a person. * Any memberdn entries that are not already members will be ignored. */ removeMember(memberdn: string | string[], groupdn: string): Promise<boolean>; private getMemberRecur; getMemberStream<T = any>(groupdn: string, attributes?: SearchOptions['attributes']): GenericReadable<LdapEntry<T>>; getMembers<T = any>(groupdn: string, attributes?: SearchOptions['attributes']): Promise<LdapEntry<T>[]>; protected templateLiteralEscape(regex: RegExp, replacements: any, strings: TemplateStringsArray, values: (string | number)[]): string; filter(strings: TemplateStringsArray, ...values: (string | number)[]): string; filterAllowWildcard(strings: TemplateStringsArray, ...values: (string | number)[]): string; dn(strings: TemplateStringsArray, ...values: (string | number)[]): string; in(values: (string | number)[], property: string): string; any(values: Record<string, (string | number)>, wildcards?: boolean): string; all(values: Record<string, (string | number)>, wildcards?: boolean): string; anyall(values: Record<string, string | number>[], wildcards?: boolean): string; } export declare class LdapEntry<T = any> { protected client: Ldap; attrs: Map<string, { type: string; values: string[] | Buffer<ArrayBufferLike>[]; }>; dn: string; constructor(data: Entry, client: Ldap); get(attr: string): string | undefined; one(attr: string): string | undefined; first(attr: string): string | undefined; all(attr: string): string[]; buffer(attr: string): Buffer<ArrayBufferLike> | undefined; buffers(attr: string): Buffer<ArrayBufferLike>[]; binary(attr: string): Buffer<ArrayBufferLike> | undefined; binaries(attr: string): Buffer<ArrayBufferLike>[]; isBinary(attr: string): boolean | "" | undefined; protected optionsCache: string[] | undefined; options(attr: string): string[]; toJSON(): T; pojo(): T; toString(): string; fullRange(attr: string): Promise<string[]>; } export {};