Skip to content
This repository was archived by the owner on May 14, 2024. It is now read-only.

Commit 9718b85

Browse files
authored
Merge pull request #2 from ldapjs/next
Changes and fixes for `ldapjs@3`
2 parents b5a65cb + 298e9e3 commit 9718b85

18 files changed

+275
-242
lines changed

Readme.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@ This package provides implementations of [LDAP controls][controls]. The
44
primary purpose of this library is to facilitate client and server
55
implementations in the [`ldapjs`](https://npm.im/ldapjs) package.
66

7-
## Note About API Stability
8-
9-
As of June 2022, this module provides an API that was directly copied from
10-
the original code in the `ldapjs` module. This API is marked as v1.0.0. The
11-
API is subject to drastic change in future semver major releases. The v1 release
12-
was published as foundational work in the overall `ldapjs` project.
13-
147
## Docs
158

169
At this time, one must reference the code to learn about the available

index.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
'use strict'
22

33
const { Ber } = require('@ldapjs/asn1')
4+
45
const Control = require('./lib/control')
5-
const {
6-
EntryChangeNotificationControl,
7-
PagedResultsControl,
8-
PersistentSearchControl,
9-
ServerSideSortingRequestControl,
10-
ServerSideSortingResponseControl,
11-
VirtualListViewRequestControl,
12-
VirtualListViewResponseControl
13-
} = require('./lib/controls')
6+
const EntryChangeNotificationControl = require('./lib/controls/entry-change-notification-control')
7+
const PagedResultsControl = require('./lib/controls/paged-results-control')
8+
const PersistentSearchControl = require('./lib/controls/persistent-search-control')
9+
const ServerSideSortingRequestControl = require('./lib/controls/server-side-sorting-request-control')
10+
const ServerSideSortingResponseControl = require('./lib/controls/server-side-sorting-response-control')
11+
const VirtualListViewRequestControl = require('./lib/controls/virtual-list-view-request-control')
12+
const VirtualListViewResponseControl = require('./lib/controls/virtual-list-view-response-control')
1413

1514
module.exports = {
1615

lib/control.js

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,51 @@ const { BerWriter } = require('@ldapjs/asn1')
1010
*/
1111
class Control {
1212
/**
13-
* Create a new baseline LDAP control.
14-
*
15-
* @param {object} [options]
16-
* @param {string} [options.type=''] The dotted decimal control type value.
17-
* @param {boolean} [options.criticality=false] Criticality value for the control.
18-
* @param {string|Buffer} [options.value] The value for the control. If this is
13+
* @typedef {object} ControlParams
14+
* @property {string} [type=''] The dotted decimal control type value.
15+
* @property {boolean} [criticality=false] Criticality value for the control.
16+
* @property {string|Buffer} [value] The value for the control. If this is
1917
* a `string` then it will be written as-is. If it is an instance of `Buffer`
2018
* then it will be written by `value.toString()` when generating a BER
2119
* instance.
2220
*/
21+
22+
/**
23+
* Create a new baseline LDAP control.
24+
*
25+
* @param {ControlParams} [options]
26+
*/
2327
constructor (options = {}) {
2428
const opts = Object.assign({ type: '', criticality: false, value: null }, options)
2529
this.type = opts.type
2630
this.criticality = opts.criticality
2731
this.value = opts.value
2832
}
2933

34+
get [Symbol.toStringTag] () {
35+
return 'LdapControl'
36+
}
37+
3038
/**
31-
* Serializes the control instance into an LDAP style control object, e.g.
32-
* `type` => `controlType`. If an instance has a `_updatePlainObject(obj)`
39+
* Serializes the control into a plain JavaScript object that can be passed
40+
* to the constructor as an options object. If an instance has a `_pojo(obj)`
3341
* method then the built object will be sent to that method and the resulting
3442
* mutated object returned.
3543
*
3644
* @returns {object} A plain JavaScript object that represents an LDAP control.
3745
*/
38-
get plainObject () {
46+
get pojo () {
3947
const obj = {
40-
controlType: this.type,
41-
criticality: this.criticality,
42-
controlValue: this.value
48+
type: this.type,
49+
value: this.value,
50+
criticality: this.criticality
4351
}
44-
return (
45-
typeof (this._updatePlainObject) === 'function'
46-
? this._updatePlainObject(obj)
47-
: obj
48-
)
52+
53+
if (typeof this._pojo === 'function') {
54+
this._pojo(obj)
55+
}
56+
57+
return obj
4958
}
5059

5160
/**

lib/control.test.js

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ const tap = require('tap')
44
const { BerWriter } = require('@ldapjs/asn1')
55
const Control = require('./control')
66

7-
tap.test('contructor', t => {
7+
tap.test('constructor', t => {
88
t.test('new no args', function (t) {
99
t.ok(new Control())
10+
t.equal(Object.prototype.toString.call(new Control()), '[object LdapControl]')
1011
t.end()
1112
})
1213

@@ -24,7 +25,35 @@ tap.test('contructor', t => {
2425
t.end()
2526
})
2627

27-
tap.test('#toBer', t => {
28+
tap.test('pojo', t => {
29+
t.test('passes through _pojo', async t => {
30+
class Foo extends Control {
31+
_pojo (obj) {
32+
obj.foo = 'foo'
33+
}
34+
}
35+
const control = new Foo()
36+
t.strictSame(control.pojo, {
37+
type: '',
38+
value: null,
39+
criticality: false,
40+
foo: 'foo'
41+
})
42+
})
43+
44+
t.test('returns basic object', async t => {
45+
const control = new Control({ type: '1.2.3', criticality: false, value: 'foo' })
46+
t.strictSame(control.pojo, {
47+
type: '1.2.3',
48+
value: 'foo',
49+
criticality: false
50+
})
51+
})
52+
53+
t.end()
54+
})
55+
56+
tap.test('toBer', t => {
2857
t.test('converts empty instance to BER', async t => {
2958
const target = new BerWriter()
3059
target.startSequence()
@@ -128,28 +157,3 @@ tap.test('#toBer', t => {
128157

129158
t.end()
130159
})
131-
132-
tap.test('#plainObject', t => {
133-
t.test('passes through _updatePlainObject', async t => {
134-
t.plan(2)
135-
const control = new Control()
136-
control._updatePlainObject = () => {
137-
t.pass()
138-
return 'foo'
139-
}
140-
const str = control.plainObject
141-
t.equal(str, 'foo')
142-
})
143-
144-
t.test('returns basic object', async t => {
145-
const control = new Control({ type: '1.2.3', criticality: false, value: 'foo' })
146-
const str = control.plainObject
147-
t.same(str, {
148-
controlType: '1.2.3',
149-
criticality: false,
150-
controlValue: 'foo'
151-
})
152-
})
153-
154-
t.end()
155-
})

lib/controls/entry-change-notification-control.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ const Control = require('../control')
2222
class EntryChangeNotificationControl extends Control {
2323
static OID = '2.16.840.1.113730.3.4.7'
2424

25+
/**
26+
* @typedef {ControlParams} EntryChangeNotificationParams
27+
* @property {EntryChangeNotificationControlValue | Buffer} [value]
28+
*/
29+
2530
/**
2631
* Creates a new persistent search control.
2732
*
28-
* @param {object} [options]
29-
* @param {EntryChangeNotificationControlValue | Buffer} [options.value]
33+
* @param {EntryChangeNotificationParams} [options]
3034
*/
3135
constructor (options = {}) {
3236
options.type = EntryChangeNotificationControl.OID

lib/controls/entry-change-notification-control.test.js

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,30 @@ tap.test('contructor', t => {
5656
t.end()
5757
})
5858

59-
tap.test('#toBer', t => {
59+
tap.test('pojo', t => {
60+
t.test('adds control value', async t => {
61+
const control = new ECNC({
62+
value: {
63+
changeType: 8,
64+
previousDN: 'dn=foo',
65+
changeNumber: 42
66+
}
67+
})
68+
t.strictSame(control.pojo, {
69+
type: ECNC.OID,
70+
criticality: false,
71+
value: {
72+
changeType: 8,
73+
previousDN: 'dn=foo',
74+
changeNumber: 42
75+
}
76+
})
77+
})
78+
79+
t.end()
80+
})
81+
82+
tap.test('toBer', t => {
6083
t.test('converts empty instance to BER', async t => {
6184
const target = new BerWriter()
6285
target.startSequence()
@@ -108,27 +131,3 @@ tap.test('#toBer', t => {
108131

109132
t.end()
110133
})
111-
112-
tap.test('#plainObject', t => {
113-
t.test('adds control value', async t => {
114-
const control = new ECNC({
115-
value: {
116-
changeType: 8,
117-
previousDN: 'dn=foo',
118-
changeNumber: 42
119-
}
120-
})
121-
const value = control.plainObject
122-
t.same(value, {
123-
controlType: ECNC.OID,
124-
criticality: false,
125-
controlValue: {
126-
changeType: 8,
127-
previousDN: 'dn=foo',
128-
changeNumber: 42
129-
}
130-
})
131-
})
132-
133-
t.end()
134-
})

lib/controls/index.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

lib/controls/paged-results-control.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ const Control = require('../control')
2121
class PagedResultsControl extends Control {
2222
static OID = '1.2.840.113556.1.4.319'
2323

24+
/**
25+
* @typedef {ControlParams} PagedResultsParams
26+
* @property {PagedResultsControlValue | Buffer} [value]
27+
*/
28+
2429
/**
2530
* Creates a new paged results control.
2631
*
27-
* @param {object} [options]
28-
* @param {PagedResultsControlValue | Buffer} [options.value]
32+
* @param {PagedResultsParams} [options]
2933
*/
3034
constructor (options = {}) {
3135
options.type = PagedResultsControl.OID

lib/controls/paged-results-control.test.js

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,28 @@ tap.test('contructor', t => {
6262
t.end()
6363
})
6464

65-
tap.test('#toBer', t => {
65+
tap.test('pojo', t => {
66+
t.test('adds control value', async t => {
67+
const control = new PSC({
68+
value: {
69+
size: 1,
70+
cookie: 'foo'
71+
}
72+
})
73+
t.same(control.pojo, {
74+
type: PSC.OID,
75+
criticality: false,
76+
value: {
77+
size: 1,
78+
cookie: Buffer.from('foo')
79+
}
80+
})
81+
})
82+
83+
t.end()
84+
})
85+
86+
tap.test('toBer', t => {
6687
t.test('converts empty instance to BER', async t => {
6788
const target = new BerWriter()
6889
target.startSequence()
@@ -116,25 +137,3 @@ tap.test('#toBer', t => {
116137

117138
t.end()
118139
})
119-
120-
tap.test('#plainObject', t => {
121-
t.test('adds control value', async t => {
122-
const control = new PSC({
123-
value: {
124-
size: 1,
125-
cookie: 'foo'
126-
}
127-
})
128-
const value = control.plainObject
129-
t.same(value, {
130-
controlType: PSC.OID,
131-
criticality: false,
132-
controlValue: {
133-
size: 1,
134-
cookie: Buffer.from('foo')
135-
}
136-
})
137-
})
138-
139-
t.end()
140-
})

lib/controls/persistent-search-control.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ const Control = require('../control')
2222
class PersistentSearchControl extends Control {
2323
static OID = '2.16.840.1.113730.3.4.3'
2424

25+
/**
26+
* @typedef {ControlParams} PersistentSearchParams
27+
* @property {PersistentSearchControlValue | Buffer} [value]
28+
*/
29+
2530
/**
2631
* Creates a new persistent search control.
2732
*
28-
* @param {object} [options]
29-
* @param {PersistentSearchControlValue | Buffer} [options.value]
33+
* @param {PersistentSearchParams} [options]
3034
*/
3135
constructor (options = {}) {
3236
options.type = PersistentSearchControl.OID

0 commit comments

Comments
 (0)