entry-change-notification-control.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use strict'
  2. const { BerReader, BerWriter } = require('@ldapjs/asn1')
  3. const isObject = require('../is-object')
  4. const hasOwn = require('../has-own')
  5. const Control = require('../control')
  6. /**
  7. * @typedef {object} EntryChangeNotificationControlValue
  8. * @property {number} changeType One of 1 (add), 2 (delete), 4 (modify),
  9. * or 8 (modifyDN).
  10. * @property {string} previousDN Only set when operation is a modifyDN op.
  11. * @property {number} changeNumber
  12. */
  13. /**
  14. * Implements:
  15. * https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-psearch-03.txt#section-5
  16. *
  17. * @extends Control
  18. */
  19. class EntryChangeNotificationControl extends Control {
  20. static OID = '2.16.840.1.113730.3.4.7'
  21. /**
  22. * @typedef {ControlParams} EntryChangeNotificationParams
  23. * @property {EntryChangeNotificationControlValue | Buffer} [value]
  24. */
  25. /**
  26. * Creates a new persistent search control.
  27. *
  28. * @param {EntryChangeNotificationParams} [options]
  29. */
  30. constructor (options = {}) {
  31. options.type = EntryChangeNotificationControl.OID
  32. super(options)
  33. this._value = {
  34. changeType: 4
  35. }
  36. if (hasOwn(options, 'value') === false) {
  37. return
  38. }
  39. if (Buffer.isBuffer(options.value)) {
  40. this.#parse(options.value)
  41. } else if (isObject(options.value)) {
  42. this._value = options.value
  43. } else {
  44. throw new TypeError('options.value must be a Buffer or Object')
  45. }
  46. }
  47. get value () {
  48. return this._value
  49. }
  50. set value (obj) {
  51. this._value = Object.assign({}, this._value, obj)
  52. }
  53. /**
  54. * Given a BER buffer that represents a
  55. * {@link EntryChangeNotificationControlValue}, read that buffer into the
  56. * current instance.
  57. */
  58. #parse (buffer) {
  59. const ber = new BerReader(buffer)
  60. /* istanbul ignore else */
  61. if (ber.readSequence()) {
  62. this._value = {
  63. changeType: ber.readInt()
  64. }
  65. /* istanbul ignore else */
  66. if (this._value.changeType === 8) {
  67. // If the operation was moddn, then parse the optional previousDN attr.
  68. this._value.previousDN = ber.readString()
  69. }
  70. this._value.changeNumber = ber.readInt()
  71. }
  72. }
  73. _toBer (ber) {
  74. const writer = new BerWriter()
  75. writer.startSequence()
  76. writer.writeInt(this._value.changeType)
  77. if (this._value.previousDN) { writer.writeString(this._value.previousDN) }
  78. if (Object.prototype.hasOwnProperty.call(this._value, 'changeNumber')) {
  79. writer.writeInt(parseInt(this._value.changeNumber, 10))
  80. }
  81. writer.endSequence()
  82. ber.writeBuffer(writer.buffer, 0x04)
  83. return ber
  84. }
  85. _updatePlainObject (obj) {
  86. obj.controlValue = this.value
  87. return obj
  88. }
  89. }
  90. module.exports = EntryChangeNotificationControl