diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index efd4988..6b2ecd0 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x, 14.x, 15.x, 16.x, 17.x, 18.x] + node-version: [15.x, 16.x, 17.x, 18.x] name: 'Integration Node v${{ matrix.node-version }}' diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..9ec07bf --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Example", + "skipFiles": ["/**"], + "program": "${workspaceFolder}/example/index.js" + } + ] +} diff --git a/README.md b/README.md index bea1782..da0e810 100644 --- a/README.md +++ b/README.md @@ -181,19 +181,43 @@ auth() The user object if `authenticate()` is success. -The user object has a `raw` field that has the raw data from the LDAP/AD server. It can be used to access buffer objects (profile pics for example). -Buffer data can now be accessed by `user.raw.profilePhoto`, etc, instead of `user.profilePhoto`. - - - +In version 2, The user object has a `raw` field that has the raw data from the LDAP/AD server. It can be used to access buffer objects (profile pics for example). +Buffer data can now be accessed by `user.raw.profilePhoto`, etc, instead of `user.profilePhoto`. +In version 3, the `raw` field is no longer used. Instead, append `;binary` to the attributes you +want to get back as buffer. Check the following example on how to get a user's profile photo: +```javascript +export async function verifyLogin(email: string, password: string) { + const options = { + //...other config options + userPassword: password, + username: email, + attributes: ['thumbnailPhoto;binary', 'givenName', 'sn', 'sAMAccountName', 'userPrincipalName', 'memberOf' ] + }; + try { + const ldapUser = await authenticate(options); + if (!ldapUser) { + return { error: "user not found" }; + } + // accessing the image + const profilePhoto = ldapUser['thumbnailPhoto;binary']; + /* using the image + + */ + return { user: ldapUser }; + } +} +``` +## Supported Node Versions +Version 2 supports Node version 12, 14, 15, 16, 17 and 18. +Version 3 supports Node version 15, 16, 17 and 18 diff --git a/index.js b/index.js index bd07a58..8a9bb53 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,18 @@ const assert = require('assert') const ldap = require('ldapjs') +// convert a SearchResultEntry object in ldapjs 3.0 +// to a user object to maintain backward compatibility + +function _searchResultToUser(pojo) { + assert(pojo.type == 'SearchResultEntry') + let user = { dn: pojo.objectName } + pojo.attributes.forEach((attribute) => { + user[attribute.type] = + attribute.values.length == 1 ? attribute.values[0] : attribute.values + }) + return user +} // bind and return the ldap client function _ldapBind(dn, password, starttls, ldapOpts) { return new Promise(function (resolve, reject) { @@ -86,8 +98,7 @@ async function _searchUser( return } res.on('searchEntry', function (entry) { - user = entry.object - user.raw = entry.raw + user = _searchResultToUser(entry.pojo) }) res.on('searchReference', function (referral) { // TODO: we don't support reference yet diff --git a/package-lock.json b/package-lock.json index 5398cbe..5b724c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,33 +1,102 @@ { "name": "ldap-authentication", - "version": "2.3.3", + "version": "3.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ldap-authentication", - "version": "2.3.3", + "version": "3.0.1", "license": "BSD-2-Clause", "dependencies": { - "ldapjs": "^2.3.3" + "ldapjs": "^3.0.1" }, "devDependencies": { - "jasmine": "^4.5.0" + "jasmine": "^4.6.0" } }, + "node_modules/@ldapjs/asn1": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-2.0.0.tgz", + "integrity": "sha512-G9+DkEOirNgdPmD0I8nu57ygQJKOOgFEMKknEuQvIHbGLwP3ny1mY+OTUYLCbCaGJP4sox5eYgBJRuSUpnAddA==" + }, + "node_modules/@ldapjs/attribute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/attribute/-/attribute-1.0.0.tgz", + "integrity": "sha512-ptMl2d/5xJ0q+RgmnqOi3Zgwk/TMJYG7dYMC0Keko+yZU6n+oFM59MjQOUht5pxJeS4FWrImhu/LebX24vJNRQ==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/change": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/change/-/change-1.0.0.tgz", + "integrity": "sha512-EOQNFH1RIku3M1s0OAJOzGfAohuFYXFY4s73wOhRm4KFGhmQQ7MChOh2YtYu9Kwgvuq1B0xKciXVzHCGkB5V+Q==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0" + } + }, + "node_modules/@ldapjs/controls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/controls/-/controls-2.0.0.tgz", + "integrity": "sha512-NpFmdIc2q83tYRGR2a3NDulKgU1e4YOgqjQmmMezCoN4Xz0tju4yB4eibQNC+Zg8YRW06KPwFPKbebDaCqFF0w==", + "dependencies": { + "@ldapjs/asn1": "^1.2.0", + "@ldapjs/protocol": "^1.2.1" + } + }, + "node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-1.2.0.tgz", + "integrity": "sha512-KX/qQJ2xxzvO2/WOvr1UdQ+8P5dVvuOLk/C9b1bIkXxZss8BaR28njXdPgFCpj5aHaf1t8PmuVnea+N9YG9YMw==" + }, + "node_modules/@ldapjs/dn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/dn/-/dn-1.0.0.tgz", + "integrity": "sha512-qPsJDC5dQU2TSkA/IpswvPEg9MU6TIjjq0UOCHtuUeD3eWihTUjHuu/dith4NFRKjBvgFnqRQvo+t0YC+3z0Rw==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/filter/-/filter-2.0.0.tgz", + "integrity": "sha512-7hMv5DNlHJk4qoGzCFGbbSV0vgvn2A7hZ4mt15557xDhw+BXjhryBvs8ANTHUpyaWvESbU+oNOsbBobNLZ45Nw==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/messages": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ldapjs/messages/-/messages-1.0.1.tgz", + "integrity": "sha512-1S/Y9QqyYTI97RJHuJqSnNTr8iXunY8KK+E0KDwNsT69X7ftxH2LIV+232/BV0KIMQ0yYTxroQAIdYmWTni1IA==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0", + "@ldapjs/change": "1.0.0", + "@ldapjs/controls": "2.0.0", + "@ldapjs/dn": "1.0.0", + "@ldapjs/filter": "2.0.0", + "@ldapjs/protocol": "1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/protocol": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ldapjs/protocol/-/protocol-1.2.1.tgz", + "integrity": "sha512-O89xFDLW2gBoZWNXuXpBSM32/KealKCTb3JGtJdtUQc7RjAk8XzrRgyz02cPAwGKwKPxy0ivuC7UP9bmN87egQ==" + }, "node_modules/abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -125,51 +194,43 @@ "dev": true }, "node_modules/jasmine": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.5.0.tgz", - "integrity": "sha512-9olGRvNZyADIwYL9XBNBst5BTU/YaePzuddK+YRslc7rI9MdTIE4r3xaBKbv2GEmzYYUfMOdTR8/i6JfLZaxSQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.6.0.tgz", + "integrity": "sha512-iq7HQ5M8ydNUspjd9vbFW9Lu+6lQ1QLDIqjl0WysEllF5EJZy8XaUyNlhCJVwOx2YFzqTtARWbS56F/f0PzRFw==", "dev": true, "dependencies": { "glob": "^7.1.6", - "jasmine-core": "^4.5.0" + "jasmine-core": "^4.6.0" }, "bin": { "jasmine": "bin/jasmine.js" } }, "node_modules/jasmine-core": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.5.0.tgz", - "integrity": "sha512-9PMzyvhtocxb3aXJVOPqBDswdgyAeSB81QnLop4npOpbqnheaTEwPc9ZloQeVswugPManznQBjD8kWDTjlnHuw==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.0.tgz", + "integrity": "sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ==", "dev": true }, - "node_modules/ldap-filter": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/ldap-filter/-/ldap-filter-0.3.3.tgz", - "integrity": "sha512-/tFkx5WIn4HuO+6w9lsfxq4FN3O+fDZeO9Mek8dCD8rTUpqzRa766BOBO7BcGkn3X86m5+cBm1/2S/Shzz7gMg==", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/ldapjs": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-2.3.3.tgz", - "integrity": "sha512-75QiiLJV/PQqtpH+HGls44dXweviFwQ6SiIK27EqzKQ5jU/7UFrl2E5nLdQ3IYRBzJ/AVFJI66u0MZ0uofKYwg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-3.0.1.tgz", + "integrity": "sha512-/bOFimHRBBMalpApgBeDNBTdQcK9wf9OCpZ3jloqJ9EPnSqCpKbGJ8cp81qHMfjlodpq8V9zgJTqWZ0/Bv/eUg==", "dependencies": { - "abstract-logging": "^2.0.0", - "asn1": "^0.2.4", + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0", + "@ldapjs/change": "1.0.0", + "@ldapjs/controls": "2.0.0", + "@ldapjs/dn": "1.0.0", + "@ldapjs/filter": "2.0.0", + "@ldapjs/messages": "1.0.1", + "@ldapjs/protocol": "^1.2.1", + "abstract-logging": "^2.0.1", "assert-plus": "^1.0.0", "backoff": "^2.5.0", - "ldap-filter": "^0.3.3", "once": "^1.4.0", - "vasync": "^2.2.0", - "verror": "^1.8.1" - }, - "engines": { - "node": ">=10.13.0" + "vasync": "^2.2.1", + "verror": "^1.10.1" } }, "node_modules/minimatch": { @@ -209,10 +270,10 @@ "node": ">= 0.6" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "node_modules/process-warning": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.1.0.tgz", + "integrity": "sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg==" }, "node_modules/vasync": { "version": "2.2.1", diff --git a/package.json b/package.json index 8053f05..ba0cf17 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ldap-authentication", - "version": "2.3.3", + "version": "3.0.1", "description": "A simple async nodejs library for LDAP user authentication", "main": "index.js", "types": "./index.d.ts", @@ -36,9 +36,9 @@ }, "homepage": "https://github.com/shaozi/ldap-authentication#readme", "dependencies": { - "ldapjs": "^2.3.3" + "ldapjs": "^3.0.1" }, "devDependencies": { - "jasmine": "^4.5.0" + "jasmine": "^4.6.0" } } diff --git a/test/test.js b/test/test.js index 8e4fba6..22d32e0 100644 --- a/test/test.js +++ b/test/test.js @@ -72,7 +72,6 @@ describe('ldap-authentication test', () => { let user = await authenticate(options) expect(user).toBeTruthy() expect(user.uid).toEqual('einstein') - expect(user.raw).toBeTruthy() }) it('Use an regular user to authenticate iteself and return attributes', async () => { let options = {