/// --- Globals // var parseDN = require('./dn').parse const EntryChangeNotificationControl = require('./controls').EntryChangeNotificationControl /// --- API // Cache used to store connected persistent search clients function PersistentSearch () { this.clientList = [] } PersistentSearch.prototype.addClient = function (req, res, callback) { if (typeof (req) !== 'object') { throw new TypeError('req must be an object') } if (typeof (res) !== 'object') { throw new TypeError('res must be an object') } if (callback && typeof (callback) !== 'function') { throw new TypeError('callback must be a function') } const log = req.log const client = {} client.req = req client.res = res log.debug('%s storing client', req.logId) this.clientList.push(client) log.debug('%s stored client', req.logId) log.debug('%s total number of clients %s', req.logId, this.clientList.length) if (callback) { callback(client) } } PersistentSearch.prototype.removeClient = function (req, res, callback) { if (typeof (req) !== 'object') { throw new TypeError('req must be an object') } if (typeof (res) !== 'object') { throw new TypeError('res must be an object') } if (callback && typeof (callback) !== 'function') { throw new TypeError('callback must be a function') } const log = req.log log.debug('%s removing client', req.logId) const client = {} client.req = req client.res = res // remove the client if it exists this.clientList.forEach(function (element, index, array) { if (element.req === client.req) { log.debug('%s removing client from list', req.logId) array.splice(index, 1) } }) log.debug('%s number of persistent search clients %s', req.logId, this.clientList.length) if (callback) { callback(client) } } function getOperationType (requestType) { switch (requestType) { case 'AddRequest': case 'add': return 1 case 'DeleteRequest': case 'delete': return 2 case 'ModifyRequest': case 'modify': return 4 case 'ModifyDNRequest': case 'modrdn': return 8 default: throw new TypeError('requestType %s, is an invalid request type', requestType) } } function getEntryChangeNotificationControl (req, obj) { // if we want to return a ECNC if (req.persistentSearch.value.returnECs) { const attrs = obj.attributes const value = {} value.changeType = getOperationType(attrs.changetype) // if it's a modDN request, fill in the previous DN if (value.changeType === 8 && attrs.previousDN) { value.previousDN = attrs.previousDN } value.changeNumber = attrs.changenumber return new EntryChangeNotificationControl({ value: value }) } else { return false } } function checkChangeType (req, requestType) { return (req.persistentSearch.value.changeTypes & getOperationType(requestType)) } /// --- Exports module.exports = { PersistentSearchCache: PersistentSearch, checkChangeType: checkChangeType, getEntryChangeNotificationControl: getEntryChangeNotificationControl }