diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..5538d2f --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +node_modules/ +coverage/ +.nyc_output/ +docs/ diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..02d96ef --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,17 @@ +module.exports = { + env: { + commonjs: true, + es2021: true, + node: true + }, + extends: [ + 'standard' + ], + rules: { + 'no-shadow': 'error', + 'no-unused-vars': ['error', { + argsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_' + }] + } +} diff --git a/lib/client/client.js b/lib/client/client.js index 5ee6090..d090cca 100644 --- a/lib/client/client.js +++ b/lib/client/client.js @@ -418,25 +418,25 @@ Client.prototype.modify = function modify (name, change, controls, callback) { const changes = [] - function changeFromObject (change) { - if (!change.operation && !change.type) { throw new Error('change.operation required') } - if (typeof (change.modification) !== 'object') { throw new Error('change.modification (object) required') } + function changeFromObject (obj) { + if (!obj.operation && !obj.type) { throw new Error('change.operation required') } + if (typeof (obj.modification) !== 'object') { throw new Error('change.modification (object) required') } - if (Object.keys(change.modification).length === 2 && - typeof (change.modification.type) === 'string' && - Array.isArray(change.modification.vals)) { + if (Object.keys(obj.modification).length === 2 && + typeof (obj.modification.type) === 'string' && + Array.isArray(obj.modification.vals)) { // Use modification directly if it's already normalized: changes.push(new Change({ - operation: change.operation || change.type, - modification: change.modification + operation: obj.operation || obj.type, + modification: obj.modification })) } else { // Normalize the modification object - Object.keys(change.modification).forEach(function (k) { + Object.keys(obj.modification).forEach(function (k) { const mod = {} - mod[k] = change.modification[k] + mod[k] = obj.modification[k] changes.push(new Change({ - operation: change.operation || change.type, + operation: obj.operation || obj.type, modification: mod })) }) @@ -679,9 +679,9 @@ Client.prototype.starttls = function starttls (options, return callback(new Error('STARTTLS already in progress or active')) } - function onSend (err, emitter) { - if (err) { - callback(err) + function onSend (sendErr, emitter) { + if (sendErr) { + callback(sendErr) return } /* @@ -697,7 +697,7 @@ Client.prototype.starttls = function starttls (options, self._starttls = null callback(err) }) - emitter.on('end', function (res) { + emitter.on('end', function (_res) { const sock = self._socket /* * Unplumb socket data during SSL negotiation. @@ -850,9 +850,9 @@ Client.prototype.connect = function connect () { } // Initialize socket events and LDAP parser. - function initSocket (url) { + function initSocket (server) { tracker = messageTrackerFactory({ - id: url ? url.href : self.socketPath, + id: server ? server.href : self.socketPath, parser: new Parser({ log: log }) }) @@ -938,7 +938,7 @@ Client.prototype.connect = function connect () { f(basicClient, callback) }, inputs: self.listeners('setup') - }, function (err, res) { + }, function (err, _res) { if (err) { self.emit('setupError', err) } @@ -1001,7 +1001,7 @@ Client.prototype.connect = function connect () { } retry.failAfter(failAfter) - retry.on('ready', function (num, delay) { + retry.on('ready', function (num, _delay) { if (self.destroyed) { // Cease connection attempts if destroyed return diff --git a/lib/client/message-tracker/id-generator.js b/lib/client/message-tracker/id-generator.js index 49423ea..3756314 100644 --- a/lib/client/message-tracker/id-generator.js +++ b/lib/client/message-tracker/id-generator.js @@ -16,8 +16,8 @@ const { MAX_MSGID } = require('../constants') module.exports = function idGeneratorFactory (start = 0) { let currentID = start return function nextID () { - const nextID = currentID + 1 - currentID = (nextID >= MAX_MSGID) ? 1 : nextID + const id = currentID + 1 + currentID = (id >= MAX_MSGID) ? 1 : id return currentID } } diff --git a/lib/client/search_pager.js b/lib/client/search_pager.js index 122ae79..d44f318 100644 --- a/lib/client/search_pager.js +++ b/lib/client/search_pager.js @@ -150,7 +150,7 @@ SearchPager.prototype._nextPage = function _nextPage (cookie) { /** * Callback provided to the client API for successful transmission. */ -SearchPager.prototype._sendCallback = function _sendCallback (err, res) { +SearchPager.prototype._sendCallback = function _sendCallback (err) { if (err) { this.finished = true if (!this.started) { diff --git a/lib/messages/abandon_response.js b/lib/messages/abandon_response.js index 27f0c7d..aa3fbc8 100644 --- a/lib/messages/abandon_response.js +++ b/lib/messages/abandon_response.js @@ -23,7 +23,7 @@ Object.defineProperties(AbandonResponse.prototype, { } }) -AbandonResponse.prototype.end = function (status) {} +AbandonResponse.prototype.end = function (_status) {} AbandonResponse.prototype._json = function (j) { return j diff --git a/lib/messages/search_entry.js b/lib/messages/search_entry.js index 21cabb8..036a663 100644 --- a/lib/messages/search_entry.js +++ b/lib/messages/search_entry.js @@ -54,7 +54,7 @@ Object.defineProperties(SearchEntry.prototype, { obj[a.type] = [] } }) - this.controls.forEach(function (element, index, array) { + this.controls.forEach(function (element) { obj.controls.push(element.json) }) return obj @@ -79,7 +79,7 @@ Object.defineProperties(SearchEntry.prototype, { obj[a.type] = [] } }) - this.controls.forEach(function (element, index, array) { + this.controls.forEach(function (element) { obj.controls.push(element.json) }) return obj diff --git a/lib/messages/unbind_response.js b/lib/messages/unbind_response.js index 77a4d39..3317984 100644 --- a/lib/messages/unbind_response.js +++ b/lib/messages/unbind_response.js @@ -31,9 +31,9 @@ Object.defineProperties(UnbindResponse.prototype, { /** * Special override that just ends the connection, if present. * - * @param {Number} status completely ignored. + * @param {Number} _status completely ignored. */ -UnbindResponse.prototype.end = function (status) { +UnbindResponse.prototype.end = function (_status) { assert.ok(this.connection) this.log.trace('%s: unbinding!', this.connection.ldap.id) diff --git a/lib/persistent_search.js b/lib/persistent_search.js index 620732e..db0ac3e 100644 --- a/lib/persistent_search.js +++ b/lib/persistent_search.js @@ -77,7 +77,7 @@ function getOperationType (requestType) { } } -function getEntryChangeNotificationControl (req, obj, callback) { +function getEntryChangeNotificationControl (req, obj) { // if we want to return a ECNC if (req.persistentSearch.value.returnECs) { const attrs = obj.attributes diff --git a/lib/server.js b/lib/server.js index 190dede..512c679 100644 --- a/lib/server.js +++ b/lib/server.js @@ -313,28 +313,28 @@ function Server (options) { return c } - function newConnection (c) { - setupConnection(c) - log.trace('new connection from %s', c.ldap.id) + function newConnection (conn) { + setupConnection(conn) + log.trace('new connection from %s', conn.ldap.id) dtrace.fire('server-connection', function () { - return [c.remoteAddress] + return [conn.remoteAddress] }) - c.parser = new Parser({ + conn.parser = new Parser({ log: options.log }) - c.parser.on('message', function (req) { - req.connection = c - req.logId = c.ldap.id + '::' + req.messageID + conn.parser.on('message', function (req) { + req.connection = conn + req.logId = conn.ldap.id + '::' + req.messageID req.startTime = new Date().getTime() - log.debug('%s: message received: req=%j', c.ldap.id, req.json) + log.debug('%s: message received: req=%j', conn.ldap.id, req.json) const res = getResponse(req) if (!res) { log.warn('Unimplemented server method: %s', req.type) - c.destroy() + conn.destroy() return false } @@ -368,7 +368,7 @@ function Server (options) { } } - res.connection = c + res.connection = conn res.logId = req.logId res.requestDN = req.dn @@ -376,10 +376,10 @@ function Server (options) { let i = 0 return (function messageIIFE (err) { - function sendError (err) { - res.status = err.code || errors.LDAP_OPERATIONS_ERROR + function sendError (sendErr) { + res.status = sendErr.code || errors.LDAP_OPERATIONS_ERROR res.matchedDN = req.suffix ? req.suffix.toString() : '' - res.errorMessage = err.message || '' + res.errorMessage = sendErr.message || '' return res.end() } @@ -388,8 +388,8 @@ function Server (options) { function next () {} // stub out next for the post chain - self._postChain.forEach(function (c) { - c.call(self, req, res, next) + self._postChain.forEach(function (cb) { + cb.call(self, req, res, next) }) } @@ -404,7 +404,7 @@ function Server (options) { const next = messageIIFE if (chain.handlers[i]) { return chain.handlers[i++].call(chain.backend, req, res, next) } - if (req.protocolOp === Protocol.LDAP_REQ_BIND && res.status === 0) { c.ldap.bindDN = req.dn } + if (req.protocolOp === Protocol.LDAP_REQ_BIND && res.status === 0) { conn.ldap.bindDN = req.dn } return after() } catch (e) { @@ -415,23 +415,23 @@ function Server (options) { }()) }) - c.parser.on('error', function (err, message) { - self.emit('error', new VError(err, 'Parser error for %s', c.ldap.id)) + conn.parser.on('error', function (err, message) { + self.emit('error', new VError(err, 'Parser error for %s', conn.ldap.id)) - if (!message) { return c.destroy() } + if (!message) { return conn.destroy() } const res = getResponse(message) - if (!res) { return c.destroy() } + if (!res) { return conn.destroy() } res.status = 0x02 // protocol error res.errorMessage = err.toString() - return c.end(res.toBer()) + return conn.end(res.toBer()) }) - c.on('data', function (data) { - log.trace('data on %s: %s', c.ldap.id, util.inspect(data)) + conn.on('data', function (data) { + log.trace('data on %s: %s', conn.ldap.id, util.inspect(data)) - c.parser.write(data) + conn.parser.write(data) }) } // end newConnection diff --git a/package.json b/package.json index cde6103..ca872a2 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,13 @@ "verror": "^1.8.1" }, "devDependencies": { + "eslint": "^7.14.0", + "eslint-config-standard": "^16.0.2", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", "get-port": "^5.1.1", "husky": "^4.2.5", - "snazzy": "^9.0.0", - "standard": "^16.0.0", "tap": "14.11.0" }, "scripts": { @@ -41,12 +44,12 @@ "test:watch": "tap -n -w --no-coverage-report", "test:integration": "tap --no-cov 'test-integration/**/*.test.js'", "test:integration:local": "docker-compose up -d && npm run test:integration && docker-compose down", - "lint": "standard | snazzy", - "lint:ci": "standard" + "lint": "eslint . --fix", + "lint:ci": "eslint ." }, "husky": { "hooks": { - "pre-commit": "npm run lint && npm run test" + "pre-commit": "npm run lint:ci && npm run test" } } } diff --git a/test-integration/.eslintrc.js b/test-integration/.eslintrc.js new file mode 100644 index 0000000..6d4700e --- /dev/null +++ b/test-integration/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + rules: { + 'no-shadow': 'off' + } +} diff --git a/test-integration/client/issues.test.js b/test-integration/client/issues.test.js index 4abcc3b..1c52148 100644 --- a/test-integration/client/issues.test.js +++ b/test-integration/client/issues.test.js @@ -32,7 +32,7 @@ tap.test('modifyDN with long name (issue #480)', t => { client.modifyDN( `cn=${longStr},ou=people,dc=planetexpress,dc=com`, targetDN, - (err, res) => { + (err) => { t.error(err) client.unbind(t.end) } diff --git a/test/.eslintrc.js b/test/.eslintrc.js new file mode 100644 index 0000000..6d4700e --- /dev/null +++ b/test/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + rules: { + 'no-shadow': 'off' + } +} diff --git a/test/client.test.js b/test/client.test.js index fe7e97c..40a93ce 100644 --- a/test/client.test.js +++ b/test/client.test.js @@ -79,7 +79,7 @@ tap.beforeEach((done, t) => { }, 250) }) - server.search('dc=timeout', function (req, res, next) { + server.search('dc=timeout', function () { // Cause the client to timeout by not sending a response. }) @@ -721,13 +721,13 @@ tap.test('GH-602 search basic with delayed event listener binding', function (t) t.error(err) setTimeout(() => { let gotEntry = 0 - res.on('searchEntry', function (entry) { + res.on('searchEntry', function () { gotEntry++ }) res.on('error', function (err) { t.fail(err) }) - res.on('end', function (res) { + res.on('end', function () { t.equal(gotEntry, 2) t.end() }) @@ -751,7 +751,7 @@ tap.test('search sizeLimit', function (t) { t.context.client.search('cn=sizelimit', { sizeLimit: limit }, function (err, res) { t2.error(err) let count = 0 - res.on('searchEntry', function (entry) { + res.on('searchEntry', function () { count++ }) res.on('end', function () { @@ -991,7 +991,7 @@ tap.test('search - sssvlv', { timeout: 10000 }, function (t) { count++ }) res.on('error', (err) => t2.error(err)) - res.on('end', function (result) { + res.on('end', function () { t2.equals(count, 10) t2.end() }) @@ -1033,7 +1033,7 @@ tap.test('search - sssvlv', { timeout: 10000 }, function (t) { count++ }) res.on('error', (err) => t2.error(err)) - res.on('end', function (result) { + res.on('end', function () { t2.equals(count, 10) t2.end() }) @@ -1048,7 +1048,7 @@ tap.test('search referral', function (t) { t.ok(res) let gotEntry = 0 let gotReferral = false - res.on('searchEntry', function (entry) { + res.on('searchEntry', function () { gotEntry++ }) res.on('searchReference', function (referral) { @@ -1261,7 +1261,7 @@ tap.test('setup action', function (t) { socketPath: t.context.socketPath }) setupClient.on('setup', function (clt, cb) { - clt.bind(BIND_DN, BIND_PW, function (err, res) { + clt.bind(BIND_DN, BIND_PW, function (err) { t.error(err) cb(err) }) @@ -1283,7 +1283,7 @@ tap.test('setup reconnect', function (t) { reconnect: true }) rClient.on('setup', function (clt, cb) { - clt.bind(BIND_DN, BIND_PW, function (err, res) { + clt.bind(BIND_DN, BIND_PW, function (err) { t.error(err) cb(err) }) @@ -1402,7 +1402,7 @@ tap.test('reconnect on server close', function (t) { reconnect: true }) clt.on('setup', function (sclt, cb) { - sclt.bind(BIND_DN, BIND_PW, function (err, res) { + sclt.bind(BIND_DN, BIND_PW, function (err) { t.error(err) cb(err) }) @@ -1426,7 +1426,7 @@ tap.test('no auto-reconnect on unbind', function (t) { reconnect: true }) clt.on('setup', function (sclt, cb) { - sclt.bind(BIND_DN, BIND_PW, function (err, res) { + sclt.bind(BIND_DN, BIND_PW, function (err) { t.error(err) cb(err) }) diff --git a/test/laundry.test.js b/test/laundry.test.js index b55ddda..a16b448 100644 --- a/test/laundry.test.js +++ b/test/laundry.test.js @@ -34,7 +34,7 @@ tap.beforeEach((done, t) => { return next() }) - server.search(suffix, function (req, res, next) { + server.search(suffix, function (req, res) { const entry = { dn: 'cn=foo, ' + suffix, attributes: { diff --git a/test/server.test.js b/test/server.test.js index 74c5c1b..c7de4a5 100644 --- a/test/server.test.js +++ b/test/server.test.js @@ -121,7 +121,7 @@ tap.test('route order', function (t) { vasync.forEachParallel({ func: runSearch, inputs: [dnShort, dnMed, dnLong] - }, function (err, results) { + }, function (err) { t.error(err) client.unbind() server.close(() => t.end()) @@ -175,7 +175,7 @@ tap.test('route absent', function (t) { }) } ] - }, function (err, result) { + }, function (err) { t.notOk(err) server.close(() => t.end()) })