123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- 'use strict'
- const warning = require('./deprecations')
- const escapeValue = require('./utils/escape-value')
- const isDottedDecimal = require('./utils/is-dotted-decimal')
- class RDN {
- #attributes = new Map()
-
- constructor (rdn = {}) {
- for (const [key, val] of Object.entries(rdn)) {
- this.setAttribute({ name: key, value: val })
- }
- }
- get [Symbol.toStringTag] () {
- return 'LdapRdn'
- }
-
- get size () {
- return this.#attributes.size
- }
-
- equals (rdn) {
- if (Object.prototype.toString.call(rdn) !== '[object LdapRdn]') {
- return false
- }
- if (this.size !== rdn.size) {
- return false
- }
- for (const key of this.keys()) {
- if (rdn.has(key) === false) return false
- if (this.getValue(key) !== rdn.getValue(key)) return false
- }
- return true
- }
-
- getValue (name) {
- return this.#attributes.get(name)?.value
- }
-
- has (name) {
- return this.#attributes.has(name)
- }
-
- keys () {
- return this.#attributes.keys()
- }
-
- setAttribute ({ name, value, options = {} }) {
- if (typeof name !== 'string') {
- throw Error('name must be a string')
- }
- const valType = Object.prototype.toString.call(value)
- if (typeof value !== 'string' && valType !== '[object BerReader]') {
- throw Error('value must be a string or BerReader')
- }
- if (Object.prototype.toString.call(options) !== '[object Object]') {
- throw Error('options must be an object')
- }
- const startsWithAlpha = str => /^[a-zA-Z]/.test(str) === true
- if (startsWithAlpha(name) === false && isDottedDecimal(name) === false) {
- throw Error('attribute name must start with an ASCII alpha character or be a numeric OID')
- }
- const attr = { value, name }
- for (const [key, val] of Object.entries(options)) {
- warning.emit('LDAP_DN_DEP_001')
- if (key === 'value') continue
- attr[key] = val
- }
- this.#attributes.set(name, attr)
- }
-
- toString ({ unescaped = false } = {}) {
- let result = ''
- const isHexEncodedValue = val => /^#([0-9a-fA-F]{2})+$/.test(val) === true
- for (const entry of this.#attributes.values()) {
- result += entry.name + '='
- if (isHexEncodedValue(entry.value)) {
- result += entry.value
- } else if (Object.prototype.toString.call(entry.value) === '[object BerReader]') {
- let encoded = '#'
- for (const byte of entry.value.buffer) {
- encoded += Number(byte).toString(16).padStart(2, '0')
- }
- result += encoded
- } else {
- result += unescaped === false ? escapeValue(entry.value) : entry.value
- }
- result += '+'
- }
- return result.substring(0, result.length - 1)
- }
-
- format () {
-
-
- warning.emit('LDAP_DN_DEP_002')
- return this.toString()
- }
-
- set (name, value, options) {
- warning.emit('LDAP_DN_DEP_003')
- this.setAttribute({ name, value, options })
- }
-
- static isRdn (rdn) {
- if (Object.prototype.toString.call(rdn) === '[object LdapRdn]') {
- return true
- }
- const isObject = Object.prototype.toString.call(rdn) === '[object Object]'
- if (isObject === false) {
- return false
- }
- if (typeof rdn.name === 'string' && typeof rdn.value === 'string') {
- return true
- }
- for (const value of Object.values(rdn)) {
- if (
- typeof value !== 'string' &&
- Object.prototype.toString.call(value) !== '[object BerReader]'
- ) return false
- }
- return true
- }
- }
- module.exports = RDN
|