total5 0.0.1-1

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.
Files changed (57) hide show
  1. package/503.html +65 -0
  2. package/CONTRIBUTING.md +55 -0
  3. package/LICENSE +211 -0
  4. package/README.md +32 -0
  5. package/api.js +289 -0
  6. package/bin/total5 +984 -0
  7. package/builders.js +1435 -0
  8. package/bundles.js +457 -0
  9. package/cache.js +58 -0
  10. package/changelog.txt +3 -0
  11. package/cluster.js +320 -0
  12. package/cms.js +625 -0
  13. package/controller.js +1419 -0
  14. package/cron.js +99 -0
  15. package/debug.js +539 -0
  16. package/edit.js +469 -0
  17. package/error.html +49 -0
  18. package/filestorage.js +1088 -0
  19. package/flow-flowstream.js +3152 -0
  20. package/flow.js +209 -0
  21. package/flowstream.js +1991 -0
  22. package/global.js +125 -0
  23. package/helpers/index.js +32 -0
  24. package/htmlparser.js +650 -0
  25. package/http.js +81 -0
  26. package/image.js +773 -0
  27. package/images.js +747 -0
  28. package/index.js +2658 -0
  29. package/jsonschema.js +691 -0
  30. package/ldap.js +792 -0
  31. package/mail.js +936 -0
  32. package/minificators.js +858 -0
  33. package/nosql-builder.js +440 -0
  34. package/nosql-querybuilder.js +316 -0
  35. package/nosql-reader.js +353 -0
  36. package/nosql-stream.js +617 -0
  37. package/nosql.js +763 -0
  38. package/openclient.js +219 -0
  39. package/package.json +32 -0
  40. package/pause.html +67 -0
  41. package/querybuilder.js +1361 -0
  42. package/release.js +167 -0
  43. package/routing.js +905 -0
  44. package/sourcemap.js +160 -0
  45. package/tangular.js +409 -0
  46. package/templates.js +145 -0
  47. package/templates.json +74 -0
  48. package/tms.js +384 -0
  49. package/tmsclient.js +125 -0
  50. package/todo.txt +7 -0
  51. package/tools/beta.sh +6 -0
  52. package/tools/release.sh +6 -0
  53. package/uibuilder.js +206 -0
  54. package/utils.js +6374 -0
  55. package/viewengine.js +880 -0
  56. package/websocket.js +1939 -0
  57. package/workers.js +129 -0
package/ldap.js ADDED
@@ -0,0 +1,792 @@
1
+ const GROWTHFACTOR = 8;
2
+
3
+ const PROTOCOL = {
4
+ // Misc
5
+ LDAP_VERSION_3: 0x03,
6
+ LBER_SET: 0x31,
7
+ LDAP_CONTROLS: 0xa0,
8
+
9
+ // Search
10
+ SCOPE_BASE_OBJECT: 0,
11
+ SCOPE_ONE_LEVEL: 1,
12
+ SCOPE_SUBTREE: 2,
13
+
14
+ NEVER_DEREF_ALIASES: 0,
15
+ DEREF_IN_SEARCHING: 1,
16
+ DEREF_BASE_OBJECT: 2,
17
+ DEREF_ALWAYS: 3,
18
+
19
+ FILTER_AND: 0xa0,
20
+ FILTER_OR: 0xa1,
21
+ FILTER_NOT: 0xa2,
22
+ FILTER_EQUALITY: 0xa3,
23
+ FILTER_SUBSTRINGS: 0xa4,
24
+ FILTER_GE: 0xa5,
25
+ FILTER_LE: 0xa6,
26
+ FILTER_PRESENT: 0x87,
27
+ FILTER_APPROX: 0xa8,
28
+ FILTER_EXT: 0xa9,
29
+
30
+ // Protocol Operations
31
+ LDAP_REQ_BIND: 0x60,
32
+ LDAP_REQ_UNBIND: 0x42,
33
+ LDAP_REQ_SEARCH: 0x63,
34
+ LDAP_REQ_MODIFY: 0x66,
35
+ LDAP_REQ_ADD: 0x68,
36
+ LDAP_REQ_DELETE: 0x4a,
37
+ LDAP_REQ_MODRDN: 0x6c,
38
+ LDAP_REQ_COMPARE: 0x6e,
39
+ LDAP_REQ_ABANDON: 0x50,
40
+ LDAP_REQ_EXTENSION: 0x77,
41
+
42
+ LDAP_REP_BIND: 0x61,
43
+ LDAP_REP_SEARCH_ENTRY: 0x64,
44
+ LDAP_REP_SEARCH_REF: 0x73,
45
+ LDAP_REP_SEARCH: 0x65,
46
+ LDAP_REP_MODIFY: 0x67,
47
+ LDAP_REP_ADD: 0x69,
48
+ LDAP_REP_DELETE: 0x6b,
49
+ LDAP_REP_MODRDN: 0x6d,
50
+ LDAP_REP_COMPARE: 0x6f,
51
+ LDAP_REP_EXTENSION: 0x78
52
+ };
53
+
54
+ const TYPES = {
55
+ EOC: 0,
56
+ Boolean: 1,
57
+ Integer: 2,
58
+ BitString: 3,
59
+ OctetString: 4,
60
+ Null: 5,
61
+ OID: 6,
62
+ ObjectDescriptor: 7,
63
+ External: 8,
64
+ Real: 9, // float
65
+ Enumeration: 10,
66
+ PDV: 11,
67
+ Utf8String: 12,
68
+ RelativeOID: 13,
69
+ Sequence: 16,
70
+ Set: 17,
71
+ NumericString: 18,
72
+ PrintableString: 19,
73
+ T61String: 20,
74
+ VideotexString: 21,
75
+ IA5String: 22,
76
+ UTCTime: 23,
77
+ GeneralizedTime: 24,
78
+ GraphicString: 25,
79
+ VisibleString: 26,
80
+ GeneralString: 28,
81
+ UniversalString: 29,
82
+ CharacterString: 30,
83
+ BMPString: 31,
84
+ Constructor: 32,
85
+ Context: 128
86
+ };
87
+
88
+ function Reader(buffer, callback) {
89
+
90
+ if (buffer instanceof Array)
91
+ buffer = Buffer.concat(buffer);
92
+
93
+ var t = this;
94
+ t.buffer = buffer;
95
+ t.size = t.buffer.length;
96
+ t.length = 0;
97
+ t.offset = 0;
98
+ t.response = [];
99
+ t.callback = callback;
100
+ }
101
+
102
+ Reader.parse = function(buffer, callback) {
103
+ var reader = new Reader(buffer, callback);
104
+ reader.parse();
105
+ };
106
+
107
+ Reader.prototype = {
108
+ get remain() {
109
+ return this.size - this.offset;
110
+ }
111
+ };
112
+
113
+ Reader.prototype.readbyte = function(peek) {
114
+
115
+ var self = this;
116
+ if (self.size - self.offset < 1)
117
+ return null;
118
+
119
+ var b = self.buffer[self.offset] & 0xff;
120
+
121
+ if (!peek)
122
+ self.offset += 1;
123
+
124
+ return b;
125
+ };
126
+
127
+ Reader.prototype.readattribute = function(attr) {
128
+
129
+ var self = this;
130
+ self.readsequence();
131
+ var id = self.readstring();
132
+
133
+ if (self.peek() === PROTOCOL.LBER_SET) {
134
+
135
+ if (self.readsequence(PROTOCOL.LBER_SET)) {
136
+ var end = self.offset + self.length;
137
+ while (self.offset < end) {
138
+
139
+ var val = self.readstring(TYPES.OctetString, true);
140
+
141
+ if (id === 'objectGUID' || id === 'objectSid')
142
+ val = val.toString('hex');
143
+ else
144
+ val = val.toString('utf8');
145
+
146
+ if (attr[id]) {
147
+ if (!(attr[id] instanceof Array))
148
+ attr[id] = [attr[id]];
149
+ attr[id].push(val);
150
+ } else
151
+ attr[id] = val;
152
+ }
153
+ }
154
+ }
155
+
156
+ return true;
157
+ };
158
+
159
+ function slice(self, length) {
160
+ self.buffer = self.buffer.slice(length);
161
+ self.offset = 0;
162
+ self.length = 0;
163
+ if (self.buffer.length)
164
+ self.parse();
165
+ else
166
+ self.finish();
167
+ }
168
+
169
+ Reader.prototype.slice = function(length) {
170
+ var self = this;
171
+ self.buffer = self.buffer.slice(length);
172
+ self.offset = 0;
173
+ self.length = 0;
174
+ if (self.buffer.length)
175
+ self.parse();
176
+ else
177
+ self.finish();
178
+ };
179
+
180
+ Reader.prototype.finish = function() {
181
+ var self = this;
182
+ self.callback(null, self.response);
183
+ // PATH.fs.writeFile('users.json', JSON.stringify(self.response, null, '\t'), () => console.log(self.response.length));
184
+ };
185
+
186
+ Reader.prototype.parse = function() {
187
+
188
+ var self = this;
189
+
190
+ // Sequence
191
+ self.readsequence();
192
+
193
+ // MessageID
194
+ self.readint();
195
+
196
+ var type = self.readsequence();
197
+ var length = self.offset + self.length;
198
+
199
+ self.size = length;
200
+
201
+ switch (type) {
202
+
203
+ case PROTOCOL.LDAP_REP_BIND:
204
+ var obj = {};
205
+ obj.status = self.readenum();
206
+ obj.dn = self.readstring();
207
+ obj.error = self.readstring();
208
+
209
+ if (obj.error) {
210
+ self.callback(obj.error, null);
211
+ return;
212
+ }
213
+
214
+ break;
215
+
216
+ case PROTOCOL.LDAP_REP_SEARCH:
217
+ var obj = {};
218
+ obj.status = self.readenum();
219
+ obj.dn = self.readstring();
220
+ obj.error = self.readstring();
221
+
222
+ if (obj.error) {
223
+ self.callback(obj.error, null);
224
+ return;
225
+ }
226
+
227
+ break;
228
+
229
+ case PROTOCOL.LDAP_REP_SEARCH_ENTRY:
230
+ var obj = {};
231
+ obj.name = self.readstring();
232
+ obj.attr = [];
233
+ self.readsequence();
234
+ var end = self.offset + self.length;
235
+ var attr = {};
236
+
237
+ while (self.offset < end)
238
+ self.readattribute(attr);
239
+
240
+ self.response.push(attr);
241
+ break;
242
+ }
243
+
244
+ setImmediate(slice, self, length);
245
+ };
246
+
247
+ Reader.prototype.peek = function() {
248
+ return this.readbyte(true);
249
+ };
250
+
251
+ Reader.prototype.readlength = function(offset) {
252
+
253
+ var self = this;
254
+
255
+ if (offset === undefined)
256
+ offset = self.offset;
257
+
258
+ if (offset >= self.size)
259
+ return null;
260
+
261
+ var lenB = self.buffer[offset++] & 0xff;
262
+ if (lenB === null)
263
+ return null;
264
+
265
+ if ((lenB & 0x80) === 0x80) {
266
+
267
+ lenB &= 0x7f;
268
+
269
+ if (lenB === 0)
270
+ throw new Error('Indefinite length not supported');
271
+
272
+ if (lenB > 4)
273
+ throw new Error('Encoding too long');
274
+
275
+ if (self.size - offset < lenB)
276
+ return null;
277
+
278
+ self.length = 0;
279
+
280
+ for (var i = 0; i < lenB; i++)
281
+ self.length = (self.length << 8) + (self.buffer[offset++] & 0xff);
282
+
283
+ } else {
284
+ // Wasn't a variable length
285
+ self.length = lenB;
286
+ }
287
+
288
+ return offset;
289
+ };
290
+
291
+ Reader.prototype.readsequence = function(tag) {
292
+
293
+ var self = this;
294
+ var seq = self.peek();
295
+ if (seq === null)
296
+ return null;
297
+
298
+ if (tag !== undefined && tag !== seq)
299
+ throw new Error('Expected 0x' + tag.toString(16) + ': got 0x' + seq.toString(16));
300
+
301
+ var o = self.readlength(self.offset + 1);
302
+ if (o === null)
303
+ return null;
304
+
305
+ self.offset = o;
306
+ return seq;
307
+ };
308
+
309
+ Reader.prototype.readint = function () {
310
+ return this.readtag(TYPES.Integer);
311
+ };
312
+
313
+ Reader.prototype.readboolean = function () {
314
+ return (this.readtag(TYPES.Boolean) === 0 ? false : true);
315
+ };
316
+
317
+ Reader.prototype.readenum = function () {
318
+ return this.readtag(TYPES.Enumeration);
319
+ };
320
+
321
+ Reader.prototype.readstring = function (tag, retbuf) {
322
+
323
+ if (!tag)
324
+ tag = TYPES.OctetString;
325
+
326
+ var self = this;
327
+ var b = self.peek();
328
+ if (b === null)
329
+ return null;
330
+
331
+ if (b !== tag)
332
+ throw new Error('Expected 0x' + tag.toString(16) + ': got 0x' + b.toString(16));
333
+
334
+ var o = self.readlength(self.offset + 1);
335
+
336
+ if (o === null)
337
+ return null;
338
+
339
+ if (self.length > self.size - o)
340
+ return null;
341
+
342
+ self.offset = o;
343
+
344
+ if (self.length === 0)
345
+ return retbuf ? Buffer.alloc(0) : '';
346
+
347
+ var str = self.buffer.slice(self.offset, self.offset + self.length);
348
+ self.offset += self.length;
349
+
350
+ return retbuf ? str : str.toString('utf8');
351
+ };
352
+
353
+ Reader.prototype.readtag = function(tag) {
354
+
355
+ var self = this;
356
+ var b = self.peek();
357
+
358
+ if (b === null)
359
+ return null;
360
+
361
+ if (b !== tag)
362
+ throw new Error('Expected 0x' + tag.toString(16) + ': got 0x' + b.toString(16));
363
+
364
+ var o = self.readlength(self.offset + 1); // stored in `length`
365
+ if (o === null)
366
+ return null;
367
+
368
+ if (self.length > 4)
369
+ throw new Error('Integer too long: ' + self.length);
370
+
371
+ if (self.length > self.size - o)
372
+ return null;
373
+
374
+ self.offset = o;
375
+
376
+ var fb = self.buffer[self.offset];
377
+ var value = 0;
378
+
379
+ for (var i = 0; i < self.length; i++) {
380
+ value <<= 8;
381
+ value |= (self.buffer[self.offset++] & 0xff);
382
+ }
383
+
384
+ if ((fb & 0x80) === 0x80 && i !== 4)
385
+ value -= (1 << (i * 8));
386
+
387
+ return value >> 0;
388
+ };
389
+
390
+ function Writer() {
391
+ var t = this;
392
+ t.buffer = Buffer.alloc(1024);
393
+ t.size = t.buffer.length;
394
+ t.offset = 0;
395
+ t.seq = [];
396
+ }
397
+
398
+ Writer.prototype.writebyte = function(value) {
399
+ var self = this;
400
+ self.ensure(1);
401
+ self.buffer[self.offset++] = value;
402
+ return self;
403
+ };
404
+
405
+ Writer.prototype.writeint = function(value, tag) {
406
+
407
+ var self = this;
408
+ var sz = 4;
409
+
410
+ if (!tag)
411
+ tag = TYPES.Integer;
412
+
413
+ while ((((value & 0xff800000) === 0) || ((value & 0xff800000) === 0xff800000 >> 0)) && (sz > 1)) {
414
+ sz--;
415
+ value <<= 8;
416
+ }
417
+
418
+ self.ensure(2 + sz);
419
+ self.buffer[self.offset++] = tag;
420
+ self.buffer[self.offset++] = sz;
421
+
422
+ while (sz-- > 0) {
423
+ self.buffer[self.offset++] = ((value & 0xff000000) >>> 24);
424
+ value <<= 8;
425
+ }
426
+
427
+ return self;
428
+ };
429
+
430
+ Writer.prototype.writestring = function (value, tag) {
431
+ var self = this;
432
+
433
+ if (!tag)
434
+ tag = TYPES.OctetString;
435
+
436
+ var length = Buffer.byteLength(value);
437
+ self.writebyte(tag);
438
+ self.writelength(length);
439
+
440
+ if (length) {
441
+ self.ensure(length);
442
+ self.buffer.write(value, self.offset);
443
+ self.offset += length;
444
+ }
445
+
446
+ return self;
447
+ };
448
+
449
+ Writer.prototype.writelength = function (length) {
450
+ var self = this;
451
+ self.ensure(4);
452
+ if (length <= 0x7f) {
453
+ self.buffer[self.offset++] = length;
454
+ } else if (length <= 0xff) {
455
+ self.buffer[self.offset++] = 0x81;
456
+ self.buffer[self.offset++] = length;
457
+ } else if (length <= 0xffff) {
458
+ self.buffer[self.offset++] = 0x82;
459
+ self.buffer[self.offset++] = length >> 8;
460
+ self.buffer[self.offset++] = length;
461
+ } else if (length <= 0xffffff) {
462
+ self.buffer[self.offset++] = 0x83;
463
+ self.buffer[self.offset++] = length >> 16;
464
+ self.buffer[self.offset++] = length >> 8;
465
+ self.buffer[self.offset++] = length;
466
+ } else
467
+ throw Error('Length too long');
468
+ return self;
469
+ };
470
+
471
+ Writer.prototype.ensure = function(length) {
472
+ var self = this;
473
+ if (self.size - self.offset < length) {
474
+ var sz = self.size * GROWTHFACTOR;
475
+ if (sz - self.offset < length)
476
+ sz += length;
477
+ var buf = Buffer.alloc(sz);
478
+ self.buffer.copy(buf, 0, 0, self.offset);
479
+ self.buffer = buf;
480
+ self.size = sz;
481
+ }
482
+ return self;
483
+ };
484
+
485
+ Writer.prototype.begsequence = function(tag) {
486
+ var self = this;
487
+
488
+ if (!tag)
489
+ tag = 48;
490
+
491
+ self.writebyte(tag);
492
+ self.seq.push(self.offset);
493
+ self.ensure(3);
494
+ self.offset += 3;
495
+ return self;
496
+ };
497
+
498
+ Writer.prototype.endsequence = function() {
499
+ var self = this;
500
+ var seq = self.seq.pop();
501
+ var start = seq + 3;
502
+ var length = self.offset - start;
503
+ if (length <= 0x7f) {
504
+ self.shift(start, length, -2);
505
+ self.buffer[seq] = length;
506
+ } else if (length <= 0xff) {
507
+ self.shift(start, length, -1);
508
+ self.buffer[seq] = 0x81;
509
+ self.buffer[seq + 1] = length;
510
+ } else if (length <= 0xffff) {
511
+ self.buffer[seq] = 0x82;
512
+ self.buffer[seq + 1] = length >> 8;
513
+ self.buffer[seq + 2] = length;
514
+ } else if (length <= 0xffffff) {
515
+ self.shift(start, length, 1);
516
+ self.buffer[seq] = 0x83;
517
+ self.buffer[seq + 1] = length >> 16;
518
+ self.buffer[seq + 2] = length >> 8;
519
+ self.buffer[seq + 3] = length;
520
+ } else
521
+ throw new Error('Sequence too long');
522
+ return self;
523
+ };
524
+
525
+ Writer.prototype.shift = function(start, length, shift) {
526
+ var self = this;
527
+ self.buffer.copy(self.buffer, start + shift, start, start + length);
528
+ self.offset += shift;
529
+ return self;
530
+ };
531
+
532
+ Writer.prototype.output = function() {
533
+ return this.buffer.slice(0, this.offset);
534
+ };
535
+
536
+ Writer.prototype.writeboolean = function(value, tag) {
537
+ var self = this;
538
+ if (!tag)
539
+ tag = TYPES.Boolean;
540
+ self.ensure(3);
541
+ self.buffer[self.offset++] = tag;
542
+ self.buffer[self.offset++] = 0x01;
543
+ self.buffer[self.offset++] = value ? 0xff : 0x00;
544
+ return self;
545
+ };
546
+
547
+ Writer.prototype.writeenum = function(value, tag) {
548
+ if (!tag)
549
+ tag = TYPES.Enumeration;
550
+ return this.writeint(value, tag);
551
+ };
552
+
553
+ Writer.prototype.writebuffer = function(buffer, tag) {
554
+ var self = this;
555
+ self.writebyte(tag);
556
+ self.writelength(buffer.length);
557
+ self.ensure(buffer.length);
558
+ buffer.copy(self.buffer, self.offset, 0, buffer.length);
559
+ self.offset += buffer.length;
560
+ return self;
561
+ };
562
+
563
+ function login(user, password) {
564
+
565
+ var writer = new Writer();
566
+
567
+ writer.begsequence();
568
+
569
+ // MessageID
570
+ writer.writeint(1);
571
+
572
+ writer.begsequence(96);
573
+
574
+ // version
575
+ writer.writeint(3);
576
+
577
+ // login
578
+ writer.writestring(user);
579
+
580
+ // pass
581
+ writer.writestring(password, TYPES.Context);
582
+
583
+ writer.endsequence();
584
+ writer.endsequence();
585
+
586
+ return writer.output();
587
+ }
588
+
589
+ function data(dn, filter, type) {
590
+
591
+ var writer = new Writer();
592
+
593
+ // === 1: beg
594
+ writer.begsequence();
595
+
596
+ // MessageID
597
+ writer.writeint(1);
598
+
599
+ // === 2: beg
600
+ writer.begsequence(99);
601
+
602
+ // keys lowercase
603
+ writer.writestring(dn);
604
+
605
+ writer.writeenum(2); // scope
606
+ writer.writeenum(0); // deref aliases
607
+ writer.writeint(0); // size limit
608
+ writer.writeint(10); // time limit
609
+ writer.writeboolean(false); // types only
610
+
611
+ // === 3: beg
612
+ /*
613
+ writer.begsequence(PROTOCOL.FILTER_OR);
614
+ var val = 'objectclass';
615
+ for (var i = 0; i < val.length; i++)
616
+ writer.writebyte(val.charCodeAt(i));
617
+ writer.endsequence();*/
618
+
619
+ writer.begsequence(PROTOCOL.FILTER_EQUALITY);
620
+ writer.writestring(filter);
621
+ writer.writebuffer(Buffer.from(type, 'ascii'), TYPES.OctetString);
622
+ writer.endsequence();
623
+ // === 3: end
624
+
625
+ // === 4: beg
626
+ writer.begsequence(48);
627
+
628
+ writer.writestring('*');
629
+
630
+ // === 4: end
631
+ writer.endsequence();
632
+
633
+ // === 2: end
634
+ writer.endsequence();
635
+
636
+ // === 1: end
637
+ writer.endsequence();
638
+
639
+ return writer.output();
640
+ }
641
+
642
+ function data2(dn, name) {
643
+
644
+ var writer = new Writer();
645
+
646
+ // === 1: beg
647
+ writer.begsequence();
648
+
649
+ // MessageID
650
+ writer.writeint(1);
651
+
652
+ // === 2: beg
653
+ writer.begsequence(99);
654
+
655
+ // keys lowercase
656
+ writer.writestring(dn);
657
+
658
+ writer.writeenum(2); // scope
659
+ writer.writeenum(0); // deref aliases
660
+ writer.writeint(0); // size limit
661
+ writer.writeint(10); // time limit
662
+ writer.writeboolean(false); // types only
663
+
664
+ writer.begsequence(PROTOCOL.FILTER_AND);
665
+
666
+ // === 3: beg
667
+ writer.begsequence(PROTOCOL.FILTER_EQUALITY);
668
+ writer.writestring('objectClass');
669
+ writer.writebuffer(Buffer.from('person', 'ascii'), TYPES.OctetString);
670
+ writer.endsequence();
671
+ // === 3: end
672
+
673
+ // === 3: beg
674
+ writer.begsequence(PROTOCOL.FILTER_EQUALITY);
675
+ writer.writestring('sAMAccountName');
676
+ writer.writebuffer(Buffer.from(name, 'ascii'), TYPES.OctetString);
677
+ writer.endsequence();
678
+ // === 3: end
679
+
680
+ writer.endsequence();
681
+
682
+ // === 4: beg
683
+ writer.begsequence(48);
684
+
685
+ writer.writestring('*');
686
+
687
+ // === 4: end
688
+ writer.endsequence();
689
+
690
+ // === 2: end
691
+ writer.endsequence();
692
+
693
+ // === 1: end
694
+ writer.endsequence();
695
+
696
+ return writer.output();
697
+ }
698
+
699
+ exports.load = function(opt, callback) {
700
+
701
+ // opt.ldap {Object} with { host: String, port: Number }
702
+ // opt.user {String}
703
+ // opt.password {String}
704
+ // opt.type {String} can be: person, group, login, profile
705
+ // opt.login {String} required for the "profile" type
706
+ // opt.dn {String}
707
+ // opt.noauth {Boolean} true skips auth
708
+
709
+ if (opt.callback)
710
+ callback = opt.callback;
711
+
712
+ var profile = opt.type === 'profile';
713
+
714
+ if (!opt.dn) {
715
+ opt.dn = opt.user;
716
+ opt.type = 'person';
717
+ profile = true;
718
+ }
719
+
720
+ F.TUtils.connect(opt.ldap, function(err, meta) {
721
+
722
+ if (err) {
723
+ callback(err);
724
+ return;
725
+ }
726
+
727
+ var buffer = [];
728
+ var auth = true;
729
+ var timeout;
730
+
731
+ var parse = function() {
732
+ Reader.parse(buffer, function(err, response) {
733
+ callback(err, profile ? (response ? response[0] : null) : response);
734
+ meta.close();
735
+ });
736
+ };
737
+
738
+ meta.ondata(function(chunk) {
739
+ if (auth) {
740
+ Reader.parse(chunk, function(err) {
741
+
742
+ if (err) {
743
+ callback(err, profile ? null : EMPTYARRAY);
744
+ meta.close();
745
+ return;
746
+ }
747
+
748
+ try {
749
+ meta.socket.write(opt.type === 'profile' ? data2(opt.dn, opt.login) : data(opt.dn, 'objectClass', opt.type));
750
+ } catch (e) {
751
+ callback(e, profile ? null : EMPTYARRAY);
752
+ meta.close();
753
+ }
754
+
755
+ auth = false;
756
+ });
757
+ } else {
758
+ buffer.push(chunk);
759
+ timeout && clearTimeout(timeout);
760
+ timeout = setTimeout(parse, 1500);
761
+ }
762
+ });
763
+
764
+ meta.onend(function() {
765
+
766
+ if (timeout)
767
+ return;
768
+
769
+ // No emitted any data in "ondata" handler
770
+ Reader.parse(buffer, function(err) {
771
+ callback(err, profile ? null : EMPTYARRAY);
772
+ });
773
+
774
+ });
775
+
776
+ if (opt.noauth) {
777
+ try {
778
+ auth = false;
779
+ meta.socket.write(opt.type === 'profile' ? data2(opt.dn, opt.login) : data(opt.dn, 'objectClass', opt.type));
780
+ } catch (e) {
781
+ callback(e, profile ? null : EMPTYARRAY);
782
+ }
783
+ } else {
784
+ try {
785
+ meta.socket.write(login(opt.user, opt.password));
786
+ } catch (e) {
787
+ callback(e, profile ? null : EMPTYARRAY);
788
+ }
789
+ }
790
+
791
+ });
792
+ };