ldap-authentication 4.2.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/codeql-analysis.yml +12 -10
- package/AGENTS.md +99 -0
- package/README.md +52 -0
- package/docker/ldap/10-ldap-test-data.ldif +14 -0
- package/example/fetch-users.mjs +36 -0
- package/example/index.js +34 -36
- package/example/starttls.mjs +40 -0
- package/example/verify-user-exists.js +45 -0
- package/index.d.ts +48 -2
- package/index.js +370 -468
- package/package.json +3 -2
- package/scripts/test-local.sh +33 -0
- package/test/authentication-result.spec.js +82 -41
- package/test/binary.spec.js +11 -10
- package/test/config.js +9 -0
- package/test/fetch-users.spec.js +23 -32
- package/test/fixtures/jpeg-photo.b64 +1 -0
- package/test/starttls.spec.js +12 -12
- package/test/test.spec.js +123 -41
- package/.github/workflows/publish.yml +0 -53
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ldap-authentication",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "A simple async nodejs library for LDAP user authentication",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"node": ">=22.0.0"
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
|
-
"test": "node test/jasmine.js"
|
|
20
|
+
"test": "node test/jasmine.js",
|
|
21
|
+
"test:local": "bash scripts/test-local.sh"
|
|
21
22
|
},
|
|
22
23
|
"repository": {
|
|
23
24
|
"type": "git",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# One-shot local integration test: start the seeded LDAP test container
|
|
3
|
+
# (docker-compose.yml), wait until it accepts an admin bind, run `npm test`,
|
|
4
|
+
# then stop the container again.
|
|
5
|
+
set -uo pipefail
|
|
6
|
+
cd "$(dirname "$0")/.."
|
|
7
|
+
|
|
8
|
+
cleanup() {
|
|
9
|
+
docker compose -f docker-compose.yml down
|
|
10
|
+
}
|
|
11
|
+
trap cleanup EXIT
|
|
12
|
+
|
|
13
|
+
docker compose -f docker-compose.yml up -d
|
|
14
|
+
|
|
15
|
+
for i in $(seq 1 30); do
|
|
16
|
+
if node -e "
|
|
17
|
+
const ldapts = require('ldapts')
|
|
18
|
+
const c = new ldapts.Client({ url: 'ldap://localhost:1389', connectTimeout: 2000 })
|
|
19
|
+
c.bind('cn=read-only-admin,dc=example,dc=com', 'password')
|
|
20
|
+
.then(() => { c.unbind(); process.exit(0) })
|
|
21
|
+
.catch(() => process.exit(1))
|
|
22
|
+
"
|
|
23
|
+
then
|
|
24
|
+
break
|
|
25
|
+
fi
|
|
26
|
+
if [ "$i" -eq 30 ]; then
|
|
27
|
+
echo 'LDAP server did not become ready in time' >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
sleep 2
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
INGITHUB=true npm test
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const {
|
|
2
2
|
authenticateResult,
|
|
3
|
+
LdapAuthenticationError,
|
|
3
4
|
AuthenticationResult,
|
|
4
5
|
AUTH_RESULT_SUCCESS,
|
|
5
6
|
AUTH_RESULT_FAILURE,
|
|
6
7
|
AUTH_RESULT_FAILURE_IDENTITY_NOT_FOUND,
|
|
7
8
|
AUTH_RESULT_FAILURE_IDENTITY_AMBIGUOUS,
|
|
8
9
|
AUTH_RESULT_FAILURE_CREDENTIAL_INVALID,
|
|
9
|
-
AUTH_RESULT_FAILURE_UNCATEGORIZED
|
|
10
|
+
AUTH_RESULT_FAILURE_UNCATEGORIZED,
|
|
10
11
|
} = require('../index.js')
|
|
11
|
-
|
|
12
|
-
const url = process.env.INGITHUB ? 'ldap://localhost:1389' : 'ldap://ldap:1389'
|
|
12
|
+
const { url, adminDn, adminPassword, userSearchBase } = require('./config')
|
|
13
13
|
|
|
14
14
|
describe('ldap-authentication test return AuthenticationResult', () => {
|
|
15
15
|
it('Use an admin user to check if user exists', async () => {
|
|
@@ -17,10 +17,10 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
17
17
|
ldapOpts: {
|
|
18
18
|
url: url,
|
|
19
19
|
},
|
|
20
|
-
adminDn:
|
|
21
|
-
adminPassword:
|
|
20
|
+
adminDn: adminDn,
|
|
21
|
+
adminPassword: adminPassword,
|
|
22
22
|
verifyUserExists: true,
|
|
23
|
-
userSearchBase:
|
|
23
|
+
userSearchBase: userSearchBase,
|
|
24
24
|
usernameAttribute: 'uid',
|
|
25
25
|
username: 'gauss',
|
|
26
26
|
}
|
|
@@ -36,10 +36,10 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
36
36
|
ldapOpts: {
|
|
37
37
|
url: url,
|
|
38
38
|
},
|
|
39
|
-
adminDn:
|
|
40
|
-
adminPassword:
|
|
39
|
+
adminDn: adminDn,
|
|
40
|
+
adminPassword: adminPassword,
|
|
41
41
|
verifyUserExists: true,
|
|
42
|
-
userSearchBase:
|
|
42
|
+
userSearchBase: userSearchBase,
|
|
43
43
|
usernameAttribute: 'uid',
|
|
44
44
|
username: 'gauss',
|
|
45
45
|
attributes: ['uid', 'sn'],
|
|
@@ -58,10 +58,10 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
58
58
|
ldapOpts: {
|
|
59
59
|
url: url,
|
|
60
60
|
},
|
|
61
|
-
adminDn:
|
|
62
|
-
adminPassword:
|
|
61
|
+
adminDn: adminDn,
|
|
62
|
+
adminPassword: adminPassword,
|
|
63
63
|
userPassword: 'password',
|
|
64
|
-
userSearchBase:
|
|
64
|
+
userSearchBase: userSearchBase,
|
|
65
65
|
usernameAttribute: 'uid',
|
|
66
66
|
username: 'gauss',
|
|
67
67
|
}
|
|
@@ -77,10 +77,10 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
77
77
|
ldapOpts: {
|
|
78
78
|
url: url,
|
|
79
79
|
},
|
|
80
|
-
adminDn:
|
|
81
|
-
adminPassword:
|
|
80
|
+
adminDn: adminDn,
|
|
81
|
+
adminPassword: adminPassword,
|
|
82
82
|
userPassword: 'password',
|
|
83
|
-
userSearchBase:
|
|
83
|
+
userSearchBase: userSearchBase,
|
|
84
84
|
usernameAttribute: 'uid',
|
|
85
85
|
username: 'gauss',
|
|
86
86
|
attributes: ['uid', 'sn'],
|
|
@@ -101,7 +101,7 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
101
101
|
},
|
|
102
102
|
userDn: 'cn=einstein,ou=users,dc=example,dc=com',
|
|
103
103
|
userPassword: 'password',
|
|
104
|
-
userSearchBase:
|
|
104
|
+
userSearchBase: userSearchBase,
|
|
105
105
|
usernameAttribute: 'uid',
|
|
106
106
|
username: 'einstein',
|
|
107
107
|
}
|
|
@@ -119,7 +119,7 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
119
119
|
},
|
|
120
120
|
userDn: 'cn=einstein,ou=users,dc=example,dc=com',
|
|
121
121
|
userPassword: 'password',
|
|
122
|
-
userSearchBase:
|
|
122
|
+
userSearchBase: userSearchBase,
|
|
123
123
|
usernameAttribute: 'uid',
|
|
124
124
|
username: 'einstein',
|
|
125
125
|
attributes: ['uid', 'sn'],
|
|
@@ -151,13 +151,13 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
151
151
|
ldapOpts: {
|
|
152
152
|
url: url,
|
|
153
153
|
},
|
|
154
|
-
adminDn:
|
|
155
|
-
adminPassword:
|
|
154
|
+
adminDn: adminDn,
|
|
155
|
+
adminPassword: adminPassword,
|
|
156
156
|
userPassword: 'password',
|
|
157
|
-
userSearchBase:
|
|
157
|
+
userSearchBase: userSearchBase,
|
|
158
158
|
usernameAttribute: 'uid',
|
|
159
159
|
username: 'gauss',
|
|
160
|
-
groupsSearchBase:
|
|
160
|
+
groupsSearchBase: userSearchBase,
|
|
161
161
|
groupClass: 'groupOfNames',
|
|
162
162
|
groupMemberAttribute: 'member',
|
|
163
163
|
groupMemberUserAttribute: 'dn',
|
|
@@ -177,10 +177,10 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
177
177
|
},
|
|
178
178
|
userDn: 'cn=gauss,ou=users,dc=example,dc=com',
|
|
179
179
|
userPassword: 'password',
|
|
180
|
-
userSearchBase:
|
|
180
|
+
userSearchBase: userSearchBase,
|
|
181
181
|
usernameAttribute: 'uid',
|
|
182
182
|
username: 'gauss',
|
|
183
|
-
groupsSearchBase:
|
|
183
|
+
groupsSearchBase: userSearchBase,
|
|
184
184
|
groupClass: 'groupOfNames',
|
|
185
185
|
groupMemberAttribute: 'member',
|
|
186
186
|
groupMemberUserAttribute: 'dn',
|
|
@@ -204,10 +204,10 @@ describe('ldap-authentication test return AuthenticationResult', () => {
|
|
|
204
204
|
},
|
|
205
205
|
userDn: 'cn=gauss,ou=users,dc=example,dc=com',
|
|
206
206
|
userPassword: 'password',
|
|
207
|
-
userSearchBase:
|
|
207
|
+
userSearchBase: userSearchBase,
|
|
208
208
|
usernameAttribute: 'uid',
|
|
209
209
|
username: 'gauss',
|
|
210
|
-
groupsSearchBase:
|
|
210
|
+
groupsSearchBase: userSearchBase,
|
|
211
211
|
groupClass: 'groupOfUniqueNames',
|
|
212
212
|
}
|
|
213
213
|
|
|
@@ -228,7 +228,7 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
228
228
|
adminDn: 'cn=not-exist,dc=example,dc=com',
|
|
229
229
|
adminPassword: 'password',
|
|
230
230
|
userPassword: 'password',
|
|
231
|
-
userSearchBase:
|
|
231
|
+
userSearchBase: userSearchBase,
|
|
232
232
|
usernameAttribute: 'uid',
|
|
233
233
|
username: 'gauss',
|
|
234
234
|
}
|
|
@@ -242,10 +242,10 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
242
242
|
ldapOpts: {
|
|
243
243
|
url: url,
|
|
244
244
|
},
|
|
245
|
-
adminDn:
|
|
245
|
+
adminDn: adminDn,
|
|
246
246
|
adminPassword: 'wrongpassword',
|
|
247
247
|
userPassword: 'password',
|
|
248
|
-
userSearchBase:
|
|
248
|
+
userSearchBase: userSearchBase,
|
|
249
249
|
usernameAttribute: 'uid',
|
|
250
250
|
username: 'gauss',
|
|
251
251
|
}
|
|
@@ -259,10 +259,10 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
259
259
|
ldapOpts: {
|
|
260
260
|
url: url,
|
|
261
261
|
},
|
|
262
|
-
adminDn:
|
|
263
|
-
adminPassword:
|
|
262
|
+
adminDn: adminDn,
|
|
263
|
+
adminPassword: adminPassword,
|
|
264
264
|
userPassword: 'password',
|
|
265
|
-
userSearchBase:
|
|
265
|
+
userSearchBase: userSearchBase,
|
|
266
266
|
usernameAttribute: 'uid',
|
|
267
267
|
username: 'wrong',
|
|
268
268
|
}
|
|
@@ -276,10 +276,10 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
276
276
|
ldapOpts: {
|
|
277
277
|
url: url,
|
|
278
278
|
},
|
|
279
|
-
adminDn:
|
|
280
|
-
adminPassword:
|
|
279
|
+
adminDn: adminDn,
|
|
280
|
+
adminPassword: adminPassword,
|
|
281
281
|
userPassword: 'wrongpassword',
|
|
282
|
-
userSearchBase:
|
|
282
|
+
userSearchBase: userSearchBase,
|
|
283
283
|
usernameAttribute: 'uid',
|
|
284
284
|
username: 'gauss',
|
|
285
285
|
}
|
|
@@ -295,7 +295,7 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
295
295
|
},
|
|
296
296
|
userDn: 'cn=not-exist,dc=example,dc=com',
|
|
297
297
|
userPassword: 'password',
|
|
298
|
-
userSearchBase:
|
|
298
|
+
userSearchBase: userSearchBase,
|
|
299
299
|
usernameAttribute: 'uid',
|
|
300
300
|
username: 'gauss',
|
|
301
301
|
}
|
|
@@ -311,7 +311,7 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
311
311
|
},
|
|
312
312
|
userDn: 'cn=gauss,dc=example,dc=com',
|
|
313
313
|
userPassword: 'wrongpassword',
|
|
314
|
-
userSearchBase:
|
|
314
|
+
userSearchBase: userSearchBase,
|
|
315
315
|
usernameAttribute: 'uid',
|
|
316
316
|
username: 'gauss',
|
|
317
317
|
}
|
|
@@ -341,7 +341,7 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
341
341
|
userDn: 'cn=einstein,ou=users,dc=example,dc=com',
|
|
342
342
|
userPassword: 'password',
|
|
343
343
|
usernameAttribute: 'wrongattribute',
|
|
344
|
-
userSearchBase:
|
|
344
|
+
userSearchBase: userSearchBase,
|
|
345
345
|
username: 'einstein',
|
|
346
346
|
}
|
|
347
347
|
|
|
@@ -358,7 +358,7 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
358
358
|
userDn: 'uid=einstein,dc=example,dc=com',
|
|
359
359
|
userPassword: 'password',
|
|
360
360
|
usernameAttribute: 'cn',
|
|
361
|
-
userSearchBase:
|
|
361
|
+
userSearchBase: userSearchBase,
|
|
362
362
|
username: 'einstein',
|
|
363
363
|
}
|
|
364
364
|
|
|
@@ -375,7 +375,7 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
375
375
|
userDn: 'uid=einstein,dc=example,dc=com',
|
|
376
376
|
userPassword: 'password',
|
|
377
377
|
usernameAttribute: 'cn',
|
|
378
|
-
userSearchBase:
|
|
378
|
+
userSearchBase: userSearchBase,
|
|
379
379
|
username: 'einstein',
|
|
380
380
|
starttls: true,
|
|
381
381
|
}
|
|
@@ -391,10 +391,10 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
391
391
|
},
|
|
392
392
|
userDn: 'cn=gauss,ou=users,dc=example,dc=com',
|
|
393
393
|
userPassword: 'password',
|
|
394
|
-
userSearchBase:
|
|
394
|
+
userSearchBase: userSearchBase,
|
|
395
395
|
usernameAttribute: 'uid',
|
|
396
396
|
username: 'gauss',
|
|
397
|
-
groupsSearchBase:
|
|
397
|
+
groupsSearchBase: userSearchBase,
|
|
398
398
|
groupClass: 'groupOfNames',
|
|
399
399
|
groupMemberAttribute: 'member',
|
|
400
400
|
groupMemberUserAttribute: 'dnWRONG',
|
|
@@ -405,6 +405,47 @@ describe('ldap-authentication negative test returns AuthenticationResult', () =>
|
|
|
405
405
|
expect(result.user).toBeTruthy()
|
|
406
406
|
expect(result.user.groups.length).toBeLessThan(1)
|
|
407
407
|
})
|
|
408
|
+
it('A username containing LDAP filter metacharacters must not change the filter', async () => {
|
|
409
|
+
// The filter below would match every user (`(uid=*)`) if the username
|
|
410
|
+
// were interpolated without escaping; escaping turns it into a literal
|
|
411
|
+
// search that matches nobody
|
|
412
|
+
let options = {
|
|
413
|
+
ldapOpts: {
|
|
414
|
+
url: url,
|
|
415
|
+
},
|
|
416
|
+
adminDn: adminDn,
|
|
417
|
+
adminPassword: adminPassword,
|
|
418
|
+
userPassword: 'password',
|
|
419
|
+
userSearchBase: userSearchBase,
|
|
420
|
+
usernameFilter: '(uid={{username}})',
|
|
421
|
+
username: 'gauss)(uid=*)',
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
let result = await authenticateResult(options)
|
|
425
|
+
expect(result).toBeInstanceOf(AuthenticationResult)
|
|
426
|
+
expect(result.code).toEqual(AUTH_RESULT_FAILURE_IDENTITY_NOT_FOUND)
|
|
427
|
+
})
|
|
428
|
+
it('Missing required options should throw LdapAuthenticationError', async () => {
|
|
429
|
+
let e = null
|
|
430
|
+
try {
|
|
431
|
+
await authenticateResult({
|
|
432
|
+
ldapOpts: {
|
|
433
|
+
url: url,
|
|
434
|
+
},
|
|
435
|
+
verifyUserExists: true,
|
|
436
|
+
adminDn: adminDn,
|
|
437
|
+
userSearchBase: userSearchBase,
|
|
438
|
+
usernameAttribute: 'uid',
|
|
439
|
+
username: 'gauss',
|
|
440
|
+
})
|
|
441
|
+
} catch (error) {
|
|
442
|
+
e = error
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
expect(e).toBeTruthy()
|
|
446
|
+
expect(e).toBeInstanceOf(LdapAuthenticationError)
|
|
447
|
+
expect(e.message).toContain('adminPassword')
|
|
448
|
+
})
|
|
408
449
|
})
|
|
409
450
|
|
|
410
451
|
describe('AuthenticationResult', () => {
|
package/test/binary.spec.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const { Change, Attribute } = require('ldapts')
|
|
4
|
+
const { authenticate } = require('../index.js')
|
|
3
5
|
const ldapts = require('ldapts')
|
|
4
|
-
const {
|
|
6
|
+
const { url, adminDn, adminPassword, userSearchBase } = require('./config')
|
|
5
7
|
|
|
6
|
-
const
|
|
8
|
+
const jpegPhotoBase64 = fs
|
|
9
|
+
.readFileSync(path.join(__dirname, 'fixtures', 'jpeg-photo.b64'), 'utf8')
|
|
10
|
+
.trim()
|
|
7
11
|
|
|
8
12
|
describe('ldap-authentication binary attributes test', () => {
|
|
9
|
-
const jpegPhotoBase64 =
|
|
10
|
-
'/9j/4AAQSkZJRgABAQEASABIAAD/2wBDACgcHiMeGSgjISMtKygwPGRBPDc3PHtYXUlkkYCZlo+AjIqgtObDoKrarYqMyP/L2u71////m8H////6/+b9//j/2wBDASstLTw1PHZBQXb4pYyl+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj/wAARCACBAGQDAREAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAECAwQF/8QALRAAAgEDAwMCBQQDAAAAAAAAAAECAxEhBBIxMkFRInEFE2GBsRU0QlJikaH/xAAXAQEBAQEAAAAAAAAAAAAAAAAAAQID/8QAGxEBAQEAAwEBAAAAAAAAAAAAAAERAhIhMUH/2gAMAwEAAhEDEQA/APMIAAKAgChp2AdwAAACBlAQUkmu5RkAAACuAAADsAZQDWQKRA7AL7gAEFCbAQDAYAAXAdwBYAogAAAAgokBgADAEr8Ab09JWqZcdq8yJpjb9Pa5qr/ROy4l6Ga6ZxfvgdoYiemqw6o49yoyAAACCiQKa4AAN9PpnWy3aP5Jbiya9ClRhBJRjby/Ji1qRqRQBMkuwMZSk2trdiys2PPqR2zaNspAAIKE0A+yA201H51TPSuSW4smvTilFJJWSOdbi0RTZQghPgK56nNwzXLXtvx4NxhiUAEABQ0nJpJcgejpkoR2rtyznWo3uRpE5S4i8hfRCrPKm0wLlUUUrgZSruXTD/oROZPISuat1s3GGRQgIKADp0kFNy8pYM2rJrshBQ4M1qNErojTOdFyjZTcfqhKWaqFPObuyAdeKlBfRhcZrT01JzXdWsXWc/U7XF5IVlqWm1waYczKhXKIKEB0aOW2uvDwZvxZ9ejbBlq+CLsZaWrMAckvSgpSW6DQVNKW6ObXRUTVd5BmuKp1M05s2USBmaABpS60Qeg41rqUXeMcszjW61auroliyi7sZaFk1YKirVnSVopyXkqajTNtSv3YouXU/oWM8nHLLZWENFCsBiaAB1aCj86tnpjlko9javBlUVY29SWO4VizNaiVBJcu/m5FJwvyFTGmqct+Como3Juz5EZrnZplLKhWAw5NDZxisW47gen8NpqOncsepmarrIBZwwOWunSf+L4ZmxqVnvI1puoU1nObs347BLS7FZLZ8x27sIwqQcJuMuUaRAGdKN5X8ZKHJu+Qrq02venpbNilnGbDB3UNXHUJ7dqmv4szfA46luVnTbf0ZNFyqUpxcKnpv2kUclWiqT9LvF8O5mtRNnZO+ChSTccAOzsGShVhSlullrhFHPObnNyfLKiAHQW2lKfngqxk3dgSyhwm4TUk3dPDIPV0OrhWltmlGr2fkxYrqrUVVg0+ez8GdHPGhLa0/uaRMFeW1K9wrd6e7vJ2XhFRjKnGqtlNtPyyTB5MrqV28nRFxnf3JgogSqp0FBKzRVZlAEKKyFCbjO6eUQexotaq6UKjtUXf+xz5ccWOmas91u2RKVjHZSlaTe210yoipqHNbY3UfyTVEI7nbyUc+r0vLiuFc1Kjz7WNItSxkmCShAAAgCeXewURbTusNBHs6LWRrpQqO1T8nOzGmtamnG1unK9gM4UknfgqNYxSzZsBuTtiOL2ZKPJ1lFU6zt0yymblRhYonuQD4KEAAOXIUkEa6f8AcQ90Sq92r2+5zioXWvY0jQqJkRXn/EeiHuywcS4NI//Z'
|
|
11
|
-
|
|
12
13
|
const baseOptions = {
|
|
13
14
|
ldapOpts: {
|
|
14
15
|
url: url,
|
|
15
16
|
},
|
|
16
|
-
adminDn:
|
|
17
|
-
adminPassword:
|
|
17
|
+
adminDn: adminDn,
|
|
18
|
+
adminPassword: adminPassword,
|
|
18
19
|
verifyUserExists: true,
|
|
19
|
-
userSearchBase:
|
|
20
|
+
userSearchBase: userSearchBase,
|
|
20
21
|
usernameAttribute: 'uid',
|
|
21
22
|
}
|
|
22
23
|
|
package/test/config.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Shared settings for the integration specs: the LDAP URL (switched to
|
|
2
|
+
// localhost:1389 when INGITHUB is set, i.e. outside the docker network) and
|
|
3
|
+
// the seeded admin account (see docker/ldap/10-ldap-test-data.ldif).
|
|
4
|
+
module.exports = {
|
|
5
|
+
url: process.env.INGITHUB ? 'ldap://localhost:1389' : 'ldap://ldap:1389',
|
|
6
|
+
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
7
|
+
adminPassword: 'password',
|
|
8
|
+
userSearchBase: 'dc=example,dc=com',
|
|
9
|
+
}
|
package/test/fetch-users.spec.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
const { fetchUsers, LdapAuthenticationError } = require('../index.js')
|
|
2
|
+
const { url, adminDn, adminPassword, userSearchBase } = require('./config')
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
+
const baseOptions = {
|
|
5
|
+
ldapOpts: {
|
|
6
|
+
url: url,
|
|
7
|
+
},
|
|
8
|
+
adminDn: adminDn,
|
|
9
|
+
adminPassword: adminPassword,
|
|
10
|
+
userSearchBase: userSearchBase,
|
|
11
|
+
}
|
|
4
12
|
|
|
5
13
|
describe('ldap-authentication fetchUsers test', () => {
|
|
6
|
-
const baseOptions = {
|
|
7
|
-
ldapOpts: {
|
|
8
|
-
url: url,
|
|
9
|
-
},
|
|
10
|
-
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
11
|
-
adminPassword: 'password',
|
|
12
|
-
userSearchBase: 'dc=example,dc=com',
|
|
13
|
-
}
|
|
14
|
-
|
|
15
14
|
it('Should return all users with the default filter', async () => {
|
|
16
15
|
let users = await fetchUsers(baseOptions)
|
|
17
16
|
|
|
18
17
|
expect(Array.isArray(users)).toBe(true)
|
|
19
|
-
expect(users.length).toBe(
|
|
18
|
+
expect(users.length).toBe(3)
|
|
20
19
|
let uids = users.map((user) => user.uid)
|
|
21
20
|
expect(uids).toContain('gauss')
|
|
22
21
|
expect(uids).toContain('einstein')
|
|
22
|
+
expect(uids).toContain('doe')
|
|
23
23
|
for (let user of users) {
|
|
24
24
|
expect(user.dn).toBeTruthy()
|
|
25
25
|
}
|
|
@@ -31,7 +31,7 @@ describe('ldap-authentication fetchUsers test', () => {
|
|
|
31
31
|
attributes: ['uid', 'sn'],
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
-
expect(users.length).toBe(
|
|
34
|
+
expect(users.length).toBe(3)
|
|
35
35
|
let gauss = users.find((user) => user.uid === 'gauss')
|
|
36
36
|
expect(gauss).toBeTruthy()
|
|
37
37
|
expect(gauss.sn).toEqual('Bar1')
|
|
@@ -55,7 +55,7 @@ describe('ldap-authentication fetchUsers test', () => {
|
|
|
55
55
|
userFilter: '(objectClass=*)',
|
|
56
56
|
})
|
|
57
57
|
|
|
58
|
-
expect(users.length).toBeGreaterThan(
|
|
58
|
+
expect(users.length).toBeGreaterThan(3)
|
|
59
59
|
let dns = users.map((user) => user.dn)
|
|
60
60
|
expect(dns).toContain('cn=gauss,ou=users,dc=example,dc=com')
|
|
61
61
|
expect(dns).toContain('cn=科学A部,ou=groups,dc=example,dc=com')
|
|
@@ -72,15 +72,6 @@ describe('ldap-authentication fetchUsers test', () => {
|
|
|
72
72
|
})
|
|
73
73
|
|
|
74
74
|
describe('ldap-authentication fetchUsers negative test', () => {
|
|
75
|
-
const baseOptions = {
|
|
76
|
-
ldapOpts: {
|
|
77
|
-
url: url,
|
|
78
|
-
},
|
|
79
|
-
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
80
|
-
adminPassword: 'password',
|
|
81
|
-
userSearchBase: 'dc=example,dc=com',
|
|
82
|
-
}
|
|
83
|
-
|
|
84
75
|
it('wrong admin password should throw LdapAuthenticationError', async () => {
|
|
85
76
|
let options = {
|
|
86
77
|
...baseOptions,
|
|
@@ -115,22 +106,22 @@ describe('ldap-authentication fetchUsers negative test', () => {
|
|
|
115
106
|
expect(e).toBeInstanceOf(LdapAuthenticationError)
|
|
116
107
|
})
|
|
117
108
|
|
|
118
|
-
it('missing
|
|
119
|
-
let options = {
|
|
120
|
-
ldapOpts: {
|
|
121
|
-
url: url,
|
|
122
|
-
},
|
|
123
|
-
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
124
|
-
adminPassword: 'password',
|
|
125
|
-
}
|
|
126
|
-
|
|
109
|
+
it('missing required options should throw LdapAuthenticationError listing all of them', async () => {
|
|
127
110
|
let e = null
|
|
128
111
|
try {
|
|
129
|
-
await fetchUsers(
|
|
112
|
+
await fetchUsers({
|
|
113
|
+
ldapOpts: {
|
|
114
|
+
url: url,
|
|
115
|
+
},
|
|
116
|
+
adminDn: adminDn,
|
|
117
|
+
})
|
|
130
118
|
} catch (error) {
|
|
131
119
|
e = error
|
|
132
120
|
}
|
|
133
121
|
|
|
134
122
|
expect(e).toBeTruthy()
|
|
123
|
+
expect(e).toBeInstanceOf(LdapAuthenticationError)
|
|
124
|
+
expect(e.message).toContain('adminPassword')
|
|
125
|
+
expect(e.message).toContain('userSearchBase')
|
|
135
126
|
})
|
|
136
127
|
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/9j/4AAQSkZJRgABAQEASABIAAD/2wBDACgcHiMeGSgjISMtKygwPGRBPDc3PHtYXUlkkYCZlo+AjIqgtObDoKrarYqMyP/L2u71////m8H////6/+b9//j/2wBDASstLTw1PHZBQXb4pYyl+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj/wAARCACBAGQDAREAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAECAwQF/8QALRAAAgEDAwMCBQQDAAAAAAAAAAECAxEhBBIxMkFRInEFE2GBsRU0QlJikaH/xAAXAQEBAQEAAAAAAAAAAAAAAAAAAQID/8QAGxEBAQEAAwEBAAAAAAAAAAAAAAERAhIhMUH/2gAMAwEAAhEDEQA/APMIAAKAgChp2AdwAAACBlAQUkmu5RkAAACuAAADsAZQDWQKRA7AL7gAEFCbAQDAYAAXAdwBYAogAAAAgokBgADAEr8Ab09JWqZcdq8yJpjb9Pa5qr/ROy4l6Ga6ZxfvgdoYiemqw6o49yoyAAACCiQKa4AAN9PpnWy3aP5Jbiya9ClRhBJRjby/Ji1qRqRQBMkuwMZSk2trdiys2PPqR2zaNspAAIKE0A+yA201H51TPSuSW4smvTilFJJWSOdbi0RTZQghPgK56nNwzXLXtvx4NxhiUAEABQ0nJpJcgejpkoR2rtyznWo3uRpE5S4i8hfRCrPKm0wLlUUUrgZSruXTD/oROZPISuat1s3GGRQgIKADp0kFNy8pYM2rJrshBQ4M1qNErojTOdFyjZTcfqhKWaqFPObuyAdeKlBfRhcZrT01JzXdWsXWc/U7XF5IVlqWm1waYczKhXKIKEB0aOW2uvDwZvxZ9ejbBlq+CLsZaWrMAckvSgpSW6DQVNKW6ObXRUTVd5BmuKp1M05s2USBmaABpS60Qeg41rqUXeMcszjW61auroliyi7sZaFk1YKirVnSVopyXkqajTNtSv3YouXU/oWM8nHLLZWENFCsBiaAB1aCj86tnpjlko9javBlUVY29SWO4VizNaiVBJcu/m5FJwvyFTGmqct+Como3Juz5EZrnZplLKhWAw5NDZxisW47gen8NpqOncsepmarrIBZwwOWunSf+L4ZmxqVnvI1puoU1nObs347BLS7FZLZ8x27sIwqQcJuMuUaRAGdKN5X8ZKHJu+Qrq02venpbNilnGbDB3UNXHUJ7dqmv4szfA46luVnTbf0ZNFyqUpxcKnpv2kUclWiqT9LvF8O5mtRNnZO+ChSTccAOzsGShVhSlullrhFHPObnNyfLKiAHQW2lKfngqxk3dgSyhwm4TUk3dPDIPV0OrhWltmlGr2fkxYrqrUVVg0+ez8GdHPGhLa0/uaRMFeW1K9wrd6e7vJ2XhFRjKnGqtlNtPyyTB5MrqV28nRFxnf3JgogSqp0FBKzRVZlAEKKyFCbjO6eUQexotaq6UKjtUXf+xz5ccWOmas91u2RKVjHZSlaTe210yoipqHNbY3UfyTVEI7nbyUc+r0vLiuFc1Kjz7WNItSxkmCShAAAgCeXewURbTusNBHs6LWRrpQqO1T8nOzGmtamnG1unK9gM4UknfgqNYxSzZsBuTtiOL2ZKPJ1lFU6zt0yymblRhYonuQD4KEAAOXIUkEa6f8AcQ90Sq92r2+5zioXWvY0jQqJkRXn/EeiHuywcS4NI//Z
|
package/test/starttls.spec.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const { authenticate, LdapAuthenticationError } = require('../index.js')
|
|
2
|
-
|
|
3
|
-
const url = process.env.INGITHUB ? 'ldap://localhost:1389' : 'ldap://ldap:1389'
|
|
2
|
+
const { url, adminDn, adminPassword, userSearchBase } = require('./config')
|
|
4
3
|
|
|
5
4
|
describe('ldap-authentication StartTLS and TLS options test', () => {
|
|
6
5
|
it('Plain LDAP with tlsOptions in ldapOpts should work (ldap:// protocol)', async () => {
|
|
@@ -38,10 +37,10 @@ describe('ldap-authentication StartTLS and TLS options test', () => {
|
|
|
38
37
|
},
|
|
39
38
|
},
|
|
40
39
|
starttls: true,
|
|
41
|
-
adminDn:
|
|
42
|
-
adminPassword:
|
|
40
|
+
adminDn: adminDn,
|
|
41
|
+
adminPassword: adminPassword,
|
|
43
42
|
userPassword: 'password',
|
|
44
|
-
userSearchBase:
|
|
43
|
+
userSearchBase: userSearchBase,
|
|
45
44
|
usernameAttribute: 'uid',
|
|
46
45
|
username: 'gauss',
|
|
47
46
|
}
|
|
@@ -73,9 +72,10 @@ describe('ldap-authentication StartTLS and TLS options test', () => {
|
|
|
73
72
|
},
|
|
74
73
|
},
|
|
75
74
|
starttls: true,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
adminDn: adminDn,
|
|
76
|
+
adminPassword: adminPassword,
|
|
77
|
+
verifyUserExists: true,
|
|
78
|
+
userSearchBase: userSearchBase,
|
|
79
79
|
usernameAttribute: 'uid',
|
|
80
80
|
username: 'einstein',
|
|
81
81
|
}
|
|
@@ -103,10 +103,10 @@ describe('ldap-authentication StartTLS and TLS options test', () => {
|
|
|
103
103
|
},
|
|
104
104
|
},
|
|
105
105
|
starttls: true,
|
|
106
|
-
adminDn:
|
|
107
|
-
adminPassword:
|
|
108
|
-
|
|
109
|
-
userSearchBase:
|
|
106
|
+
adminDn: adminDn,
|
|
107
|
+
adminPassword: adminPassword,
|
|
108
|
+
userPassword: 'password',
|
|
109
|
+
userSearchBase: userSearchBase,
|
|
110
110
|
usernameAttribute: 'uid',
|
|
111
111
|
username: 'gauss',
|
|
112
112
|
}
|