@@ -6,93 +6,164 @@ const { search } = require('@ldapjs/protocol')
6
6
const escapeFilterValue = require ( '../utils/escape-filter-value' )
7
7
const testValues = require ( '../utils/test-values' )
8
8
const getAttributeValue = require ( '../utils/get-attribute-value' )
9
+ const warning = require ( '../deprecations' )
9
10
10
11
/**
11
12
* Represents a filter that matches substrings withing LDAP entry attribute
12
13
* values, e.g. `(cn=*f*o*o)`.
13
14
*/
14
15
class SubstringFilter extends FilterString {
15
- #subInitial
16
- #subAny = [ ]
17
- #subFinal
16
+ #initial
17
+ #any = [ ]
18
+ #final
19
+
20
+ /**
21
+ * Internal helper for backwards compatibility.
22
+ * @type {Boolean }
23
+ */
24
+ #constructedWithSubPrefix
18
25
19
26
/**
20
27
* @typedef {FilterStringParams } SubstringParams
21
28
* @property {string } input.attribute The attribute to test against.
22
- * @property {string } [subInitial] Text that must appear at the start
23
- * of a value and may not overlap any value of `subAny` or `subFinal`.
24
- * @property {string[] } [subAny] Text items that must appear in the
25
- * attribute value that do not overlap with `subInitial`, `subFinal`, or
26
- * any other `subAny` item.
27
- * @property {string } [subFinal] Text that must appear at the end of
28
- * the attribute value. May not overlap with `subInitial` or any `subAny`
29
+ * @property {string } [initial] Text that must appear at the start
30
+ * of a value and may not overlap any value of `any` or `final`.
31
+ * @property {string } [subInitial] Deprecated, use `initial`.
32
+ * @property {string[] } [any] Text items that must appear in the
33
+ * attribute value that do not overlap with `initial`, `final`, or
34
+ * any other `any` item.
35
+ * @property {string[] } [subAny] Deprecated, use `any`.
36
+ * @property {string } [final] Text that must appear at the end of
37
+ * the attribute value. May not overlap with `initial` or any `any`
29
38
* item.
39
+ * @property {string } [subFinal] Deprecated, use `final`.
30
40
*/
31
41
32
42
/**
33
43
* @param {SubstringParams } input
34
44
*
35
45
* @throws When any input parameter is of an incorrect type.
36
46
*/
37
- constructor ( { attribute, subInitial, subAny = [ ] , subFinal } = { } ) {
47
+ constructor ( { attribute, initial, subInitial, any = [ ] , subAny = [ ] , final, subFinal } = { } ) {
48
+ if ( subInitial ) {
49
+ warning . emit ( 'LDAP_FILTER_DEP_002' )
50
+ initial = subInitial
51
+ }
52
+
53
+ if ( Array . isArray ( subAny ) && subAny . length > 0 ) {
54
+ warning . emit ( 'LDAP_FILTER_DEP_003' )
55
+ any = subAny
56
+ }
57
+
58
+ if ( subFinal ) {
59
+ warning . emit ( 'LDAP_FILTER_DEP_004' )
60
+ final = subFinal
61
+ }
62
+
38
63
if ( typeof attribute !== 'string' || attribute . length < 1 ) {
39
64
throw Error ( 'attribute must be a string of at least one character' )
40
65
}
66
+ if ( Array . isArray ( any ) === false ) {
67
+ throw Error ( 'any must be an array of items' )
68
+ }
41
69
if ( Array . isArray ( subAny ) === false ) {
42
70
throw Error ( 'subAny must be an array of items' )
43
71
}
44
- if ( subFinal && typeof subFinal !== 'string' ) {
45
- throw Error ( 'subFinal must be a string' )
72
+ if ( final && typeof final !== 'string' ) {
73
+ throw Error ( 'final must be a string' )
46
74
}
47
75
48
76
super ( { attribute } )
49
77
50
- this . #subInitial = subInitial
51
- Array . prototype . push . apply ( this . #subAny, subAny )
52
- this . #subFinal = subFinal
78
+ this . #initial = initial
79
+ Array . prototype . push . apply ( this . #any, any )
80
+ this . #final = final
81
+ this . #constructedWithSubPrefix = subInitial || subFinal || subAny . length > 0
53
82
54
83
Object . defineProperties ( this , {
55
84
TAG : { value : search . FILTER_SUBSTRINGS } ,
56
85
type : { value : 'SubstringFilter' }
57
86
} )
58
87
}
59
88
89
+ /**
90
+ * @type {string }
91
+ */
92
+ get initial ( ) {
93
+ return this . #initial
94
+ }
95
+
96
+ /**
97
+ * @type {string[] }
98
+ */
99
+ get any ( ) {
100
+ return this . #any
101
+ }
102
+
103
+ /**
104
+ * @type {string }
105
+ */
106
+ get final ( ) {
107
+ return this . #final
108
+ }
109
+
110
+ /**
111
+ * @deprecated 2023-06-29 Use `initial` instead.
112
+ * @type {string }
113
+ */
60
114
get subInitial ( ) {
61
- return this . #subInitial
115
+ return this . #initial
62
116
}
63
117
118
+ /**
119
+ * @deprecated 2023-06-29 Use `any` instead.
120
+ * @type {string[] }
121
+ */
64
122
get subAny ( ) {
65
- return this . #subAny
123
+ return this . #any
66
124
}
67
125
126
+ /**
127
+ * @deprecated 2023-06-29 Use `final` instead.
128
+ * @type {string }
129
+ */
68
130
get subFinal ( ) {
69
- return this . #subFinal
131
+ return this . #final
70
132
}
71
133
72
134
get json ( ) {
73
- return {
74
- type : this . type ,
75
- subInitial : this . #subInitial,
76
- subAny : this . #subAny,
77
- subFinal : this . #subFinal
135
+ if ( this . #constructedWithSubPrefix) {
136
+ return {
137
+ type : this . type ,
138
+ subInitial : this . #initial,
139
+ subAny : this . #any,
140
+ subFinal : this . #final
141
+ }
142
+ } else {
143
+ return {
144
+ type : this . type ,
145
+ initial : this . #initial,
146
+ any : this . #any,
147
+ final : this . #final
148
+ }
78
149
}
79
150
}
80
151
81
152
toString ( ) {
82
153
let result = '(' + escapeFilterValue ( this . attribute ) + '='
83
154
84
- if ( this . #subInitial ) {
85
- result += escapeFilterValue ( this . #subInitial )
155
+ if ( this . #initial ) {
156
+ result += escapeFilterValue ( this . #initial )
86
157
}
87
158
88
159
result += '*'
89
160
90
- for ( const any of this . #subAny ) {
161
+ for ( const any of this . #any ) {
91
162
result += escapeFilterValue ( any ) + '*'
92
163
}
93
164
94
- if ( this . #subFinal ) {
95
- result += escapeFilterValue ( this . #subFinal )
165
+ if ( this . #final ) {
166
+ result += escapeFilterValue ( this . #final )
96
167
}
97
168
98
169
result += ')'
@@ -105,7 +176,7 @@ class SubstringFilter extends FilterString {
105
176
* object.
106
177
*
107
178
* @example
108
- * const filter = new EqualityFilter({ attribute: 'foo', subInitial : 'bar' })
179
+ * const filter = new EqualityFilter({ attribute: 'foo', initial : 'bar' })
109
180
* assert.equal(filter.matches({ foo: 'bar' }), true)
110
181
*
111
182
* @param {object } obj An object to check for match.
@@ -137,11 +208,11 @@ class SubstringFilter extends FilterString {
137
208
138
209
let re = ''
139
210
140
- if ( this . #subInitial ) { re += '^' + escapeRegExp ( this . #subInitial ) + '.*' }
141
- this . #subAny . forEach ( function ( s ) {
211
+ if ( this . #initial ) { re += '^' + escapeRegExp ( this . #initial ) + '.*' }
212
+ this . #any . forEach ( function ( s ) {
142
213
re += escapeRegExp ( s ) + '.*'
143
214
} )
144
- if ( this . #subFinal ) { re += escapeRegExp ( this . #subFinal ) + '$' }
215
+ if ( this . #final ) { re += escapeRegExp ( this . #final ) + '$' }
145
216
146
217
const matcher = new RegExp ( re )
147
218
return testValues ( {
@@ -156,15 +227,15 @@ class SubstringFilter extends FilterString {
156
227
ber . writeString ( this . attribute )
157
228
ber . startSequence ( )
158
229
159
- if ( this . #subInitial ) { ber . writeString ( this . #subInitial , 0x80 ) }
230
+ if ( this . #initial ) { ber . writeString ( this . #initial , 0x80 ) }
160
231
161
- if ( this . #subAny . length > 0 ) {
162
- for ( const sub of this . #subAny ) {
232
+ if ( this . #any . length > 0 ) {
233
+ for ( const sub of this . #any ) {
163
234
ber . writeString ( sub , 0x81 )
164
235
}
165
236
}
166
237
167
- if ( this . #subFinal ) { ber . writeString ( this . #subFinal , 0x82 ) }
238
+ if ( this . #final ) { ber . writeString ( this . #final , 0x82 ) }
168
239
169
240
ber . endSequence ( )
170
241
@@ -190,9 +261,9 @@ class SubstringFilter extends FilterString {
190
261
throw Error ( `expected substring filter sequence ${ expected } , got ${ found } ` )
191
262
}
192
263
193
- let subInitial
194
- const subAny = [ ]
195
- let subFinal
264
+ let initial
265
+ const any = [ ]
266
+ let final
196
267
197
268
const attribute = reader . readString ( )
198
269
reader . readSequence ( )
@@ -204,18 +275,18 @@ class SubstringFilter extends FilterString {
204
275
const tag = reader . peek ( )
205
276
switch ( tag ) {
206
277
case 0x80 : { // Initial
207
- subInitial = reader . readString ( tag )
278
+ initial = reader . readString ( tag )
208
279
break
209
280
}
210
281
211
282
case 0x81 : { // Any
212
283
const anyVal = reader . readString ( tag )
213
- subAny . push ( anyVal )
284
+ any . push ( anyVal )
214
285
break
215
286
}
216
287
217
288
case 0x82 : { // Final
218
- subFinal = reader . readString ( tag )
289
+ final = reader . readString ( tag )
219
290
break
220
291
}
221
292
@@ -225,7 +296,7 @@ class SubstringFilter extends FilterString {
225
296
}
226
297
}
227
298
228
- return new SubstringFilter ( { attribute, subInitial , subAny , subFinal } )
299
+ return new SubstringFilter ( { attribute, initial , any , final } )
229
300
}
230
301
}
231
302
0 commit comments