wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
'use strict'
 
const LdapResult = require('../ldap-result')
const { operations } = require('@ldapjs/protocol')
 
/**
 * Implements the extension response message as described in
 * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.12.
 *
 * The type of response is impossible to determine in isolation.
 * Most EXTENSION responses do not include the request OID. And they
 * all encode their values in unique ways. Therefore, this object's
 * {@link parseToPojo} never attempts to parse the response value.
 * Instead, if it is present, it reads the value as a buffer and
 * encodes it into a hexadecimal string prefixed with a `<buffer>`
 * token. This string is then used by the `#fromExtension` method
 * on specific implementations to build a new object. It is left up to
 * the implementor to know when certain responses are expected and
 * to act accordingly.
 */
class ExtensionResponse extends LdapResult {
  #responseName
  #responseValue
 
  /**
   * @typedef {LdapResultOptions} ExtensionResponseOptions
   * @property {string|undefined} [responseName] The name of the extension, i.e.
   * OID for the response.
   * @property {string|undefined} [responseValue] The value for the
   * response. It may be a buffer string; such a string is a series of
   * hexadecimal pairs preceded by the token `<buffer>`. Buffer strings
   * are used by specific response object types to get that type's specific
   * encoded value.
   */
 
  /**
   * @param {ExtensionResponseOptions} [options]
   */
  constructor (options = {}) {
    options.protocolOp = operations.LDAP_RES_EXTENSION
    super(options)
 
    this.responseName = options.responseName
    this.responseValue = options.responseValue
  }
 
  /**
   * The OID, if any, of the response.
   *
   * @returns {string|undefined}
   */
  get responseName () {
    return this.#responseName
  }
 
  /**
   * Define the name (OID) of the response.
   *
   * @param {string} value
   */
  set responseName (value) {
    this.#responseName = value
  }
 
  /**
   * The response value, if any. For specific extensions that
   * are not simple string values, the initial value is a buffer string.
   * That is, it is a hexadecimal string of bytes prefixed with `<buffer>`.
   * To parse this value, use a specific extension's `#fromResponse` method.
   *
   * @returns {string|undefined}
   */
  get responseValue () {
    return this.#responseValue
  }
 
  /**
   * Set the response value. Should be a buffer string if the value is
   * an encoded value.
   *
   * @param {string} value
   */
  set responseValue (value) {
    this.#responseValue = value
  }
 
  /**
   * The name of the request type.
   *
   * @type {string}
   */
  get type () {
    return 'ExtensionResponse'
  }
 
  /**
   * Internal use only. Used to write the response name and
   * response value into the BER object.
   *
   * @param {import('@ldapjs/asn1').BerWriter} ber
   *
   * @returns {import('@ldapjs/asn1').BerWriter}
   */
  _writeResponse (ber) {
    if (this.responseName) {
      ber.writeString(this.responseName, 0x8a)
    }
 
    if (this.responseValue === undefined) {
      return ber
    }
 
    switch (this.responseName) {
      default: {
        // We assume the value is a plain string since
        // we do not recognize the response OID, or we
        // know it would be a plain string.
        ber.writeString(this.responseValue, 0x8b)
      }
    }
 
    return ber
  }
 
  /**
   * Implements the standardized `parseToPojo` method.
   *
   * @see LdapMessage.parseToPojo
   *
   * @param {import('@ldapjs/asn1').BerReader} ber
   *
   * @returns {object}
   */
  static parseToPojo (ber) {
    const pojo = LdapResult._parseToPojo({
      opCode: operations.LDAP_RES_EXTENSION,
      berReader: ber
    })
 
    let responseName
    if (ber.peek() === 0x8a) {
      responseName = ber.readString(0x8a)
    }
 
    if (ber.peek() !== 0x8b) {
      return { ...pojo, responseName }
    }
 
    const valueBuffer = ber.readTag(0x8b)
    const responseValue = `<buffer>${valueBuffer.toString('hex')}`
 
    return { ...pojo, responseName, responseValue }
  }
}
 
module.exports = ExtensionResponse