ldap-authentication icon indicating copy to clipboard operation
ldap-authentication copied to clipboard

attributes with ;binary is returned as Buffer instead of base64-encoded strings in v3.3.3

Open mikecat opened this issue 10 months ago • 4 comments

The README.md says:

Instead, append ;binary to the attributes you want to get back as base64-encoded string.

However, v3.3.3 seems returning attributes with ;binary as Buffer, not base64-encoded strings.

This behavior should either be documented or be reverted to return as base64-encoded strings as v3.2.6 did.

mikecat avatar Feb 25 '25 10:02 mikecat

What if you don't use the ;binary? Does it return base64 or Buffer?

shaozi avatar Feb 25 '25 23:02 shaozi

No, broken primitive string is returned. Some data was reprensented as "�" and it looked impossible to recover original data from the strign.

mikecat avatar Feb 26 '25 10:02 mikecat

Fixed in v3.3.4. Can you give it a try? @mikecat

shaozi avatar Feb 27 '25 03:02 shaozi

I'm using https://github.com/rroemhild/docker-test-openldap to test LDAP, it contains some pre-loaded data, including JPEG profile photos. it appears that some LDAP servers (as this one) don't support appending ;binary to attribute listings. I couldn't parse the contents because if I don't specify anything, I get a broken encoded string. However if i specify the ;binary suffix, I get a empty array (which is the default when a attribute isn't found?).

It's similar to https://github.com/ldapts/ldapts/issues/82

The README of ldapts says

Sometimes you may want to get a buffer back instead of a string for an attribute value. Depending on the server software, you may be able to append ;binary (the binary attribute subtype) to the attribute name, to have the value returned as a Buffer.

const searchResults = await ldapClient.search('ou=Users,o=5be4c382c583e54de6a3ff52,dc=jumpcloud,dc=com', {
   filter: '([email protected])',
   attributes: ['jpegPhoto;binary'],
});

However, some servers are very strict when it comes to the binary attribute subtype and will only acknowledge it if there is an associated AN.1 type or valid BER encoding. In those cases, you can tell ldapts to explicitly return a Buffer for an attribute:

const searchResult = await client.search('ou=Users,o=5be4c382c583e54de6a3ff52,dc=jumpcloud,dc=com', {
   filter: '([email protected])',
   explicitBufferAttributes: ['jpegPhoto'],
});

I think the solution would be to pass the explicitBufferAttributes option when calling ldapts client.search function, but since some servers allow this and others don't, perhaps this should be a top-level option you could pass when calling this module's exported authenticate function. This would support bot methods and, as a new option, would not break backward compatbility, like so:

const result = await authenticate({
 /** all other options */
 explicitBufferAttributes: ['jpegPhoto']
});

console.log(result.jpegPhoto);
console.log("Is Buffer?", result.jpegPhoto instanceof Buffer);
console.log("Typeof:", typeof result.jpegPhoto);
---
<Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 60 00 60 00 00 ff e1 00 60 45 78 69 66 00 00 49 49 2a 00 08 00 00 00 02 00 31 01 02 00 07 00 00 00 26 00 ... 26476 more bytes>
Is Buffer? true
Typeof: object

Would this be acceptable?

erickweil avatar Jun 19 '25 15:06 erickweil