UNPKG

@ldapjs/messages

Version:

API for creating and parsing LDAP messages

223 lines (198 loc) 5.36 kB
'use strict' const LdapMessage = require('../ldap-message') const { operations } = require('@ldapjs/protocol') const { DN } = require('@ldapjs/dn') /** * Implements the modifydn request message as described in * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.9. */ class ModifyDnRequest extends LdapMessage { #entry #newRdn #deleteOldRdn #newSuperior /** * @typedef {LdapMessageOptions} ModifyDnRequestOptions * @property {string|null} [entry=null] The path to the LDAP object. * @property {string|null} [newRdn=null] Path to the new object for the * entry. * @property {boolean} [deleteOldRdn=false] Indicates if attributes * should be removed in the new RDN that were in the old RDN but not the * new one. * @property {string} [newSuperior] Path for the new parent for * the RDN. */ /** * @param {ModifyDnRequestOptions} [options] * * @throws When an option is invalid (e.g. `deleteOldRdn` is not a boolean * value). */ constructor (options = {}) { options.protocolOp = operations.LDAP_REQ_MODRDN super(options) this.entry = options.entry || '' this.newRdn = options.newRdn || '' this.deleteOldRdn = options.deleteOldRdn ?? false this.newSuperior = options.newSuperior } /** * The directory path to the object to modify. * * @type {import('@ldapjs/dn').DN} */ get entry () { return this.#entry } /** * Define the entry path to the LDAP object. * * @param {string | import('@ldapjs/dn').dn} value */ set entry (value) { if (typeof value === 'string') { this.#entry = DN.fromString(value) } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { this.#entry = value } else { throw Error('entry must be a valid DN string or instance of LdapDn') } } /** * Alias of {@link entry}. * * @type {import('@ldapjs/dn').DN} */ get _dn () { return this.#entry } /** * The new directory path for the object. * * @returns {import('@ldapjs/dn').DN} */ get newRdn () { return this.#newRdn } /** * Define the new entry path to the LDAP object. * * @param {string | import('@ldapjs/dn').DN} value */ set newRdn (value) { if (typeof value === 'string') { this.#newRdn = DN.fromString(value) } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { this.#newRdn = value } else { throw Error('newRdn must be a valid DN string or instance of LdapDn') } } /** * Indicates if the old RDN should be removed or not. * * @returns {boolean} */ get deleteOldRdn () { return this.#deleteOldRdn } set deleteOldRdn (value) { if (typeof value !== 'boolean') { throw Error('deleteOldRdn must be a boolean value') } this.#deleteOldRdn = value } /** * The new superior for the entry, if any is defined. * * @returns {undefined | import('@ldapjs/dn').DN} */ get newSuperior () { return this.#newSuperior } /** * Define the new superior path. * * @param {undefined | string | import('@ldapjs/dn').DN} value */ set newSuperior (value) { if (value) { if (typeof value === 'string') { this.#newSuperior = DN.fromString(value) } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { this.#newSuperior = value } else { throw Error('newSuperior must be a valid DN string or instance of LdapDn') } } else { this.#newSuperior = undefined } } /** * The name of the request type. * * @type {string} */ get type () { return 'ModifyDnRequest' } /** * Internal use only. * * @param {import('@ldapjs/asn1').BerWriter} ber * * @returns {import('@ldapjs/asn1').BerWriter} */ _toBer (ber) { ber.startSequence(operations.LDAP_REQ_MODRDN) ber.writeString(this.#entry.toString()) ber.writeString(this.#newRdn.toString()) ber.writeBoolean(this.#deleteOldRdn) /* istanbul ignore else */ if (this.#newSuperior !== undefined) { ber.writeString(this.#newSuperior.toString(), 0x80) } ber.endSequence() return ber } /** * Internal use only. * * @param {object} * * @returns {object} */ _pojo (obj = {}) { obj.entry = this.#entry.toString() obj.newRdn = this.#newRdn.toString() obj.deleteOldRdn = this.#deleteOldRdn obj.newSuperior = this.#newSuperior ? this.#newSuperior.toString() : undefined return obj } /** * Implements the standardized `parseToPojo` method. * * @see LdapMessage.parseToPojo * * @param {import('@ldapjs/asn1').BerReader} ber * * @returns {object} */ static parseToPojo (ber) { const protocolOp = ber.readSequence() if (protocolOp !== operations.LDAP_REQ_MODRDN) { const op = protocolOp.toString(16).padStart(2, '0') throw Error(`found wrong protocol operation: 0x${op}`) } const entry = ber.readString() const newRdn = ber.readString() const deleteOldRdn = ber.readBoolean() let newSuperior /* istanbul ignore else */ if (ber.peek() === 0x80) { newSuperior = ber.readString(0x80) } return { protocolOp, entry, newRdn, deleteOldRdn, newSuperior } } } module.exports = ModifyDnRequest