Better JSDoc and other linter errors fixed

Disabled no-invalid-this since this is now very much bind based
This commit is contained in:
Vesa Poikajärvi
2017-06-01 19:15:54 +03:00
parent 8e2f1a5750
commit 868142e50b
4 changed files with 238 additions and 72 deletions
+74
View File
@@ -0,0 +1,74 @@
{
"env": {
"node": true
},
"extends": "eslint:recommended",
"rules": {
"indent": ["error", 2],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "single"],
"semi": ["error", "always"],
"valid-jsdoc": ["error"],
"require-jsdoc": ["error"],
"object-curly-spacing": ["error", "always"],
"space-before-function-paren": ["error", "never"],
"default-case": ["error"],
"guard-for-in": ["error"],
"no-caller": ["error"],
"no-empty-function": ["error"],
"no-eval": ["error"],
"no-extend-native": ["error"],
"no-extra-bind": ["error"],
"no-floating-decimal": ["error"],
"no-implied-eval": ["error"],
"no-labels": ["error"],
"no-lone-blocks": ["error"],
"no-loop-func": ["error"],
"no-param-reassign": ["error"],
"no-restricted-properties": ["error"],
"no-return-assign": ["error"],
"no-self-compare": ["error"],
"no-sequences": ["error"],
"no-throw-literal": ["error"],
"no-unmodified-loop-condition": ["error"],
"no-unused-expressions": ["error", { "allowShortCircuit": true }],
"no-useless-call": ["error"],
"no-useless-concat": ["error"],
"no-useless-escape": ["error"],
"no-void": ["error"],
"no-with": ["error"],
"radix": ["error", "always"],
"no-catch-shadow": ["error"],
"no-shadow": ["error"],
"no-shadow-restricted-names": ["error"],
"no-use-before-define": ["error"],
"callback-return": ["error"],
"global-require": ["error"],
"no-mixed-requires": ["error"],
"handle-callback-err": ["error"],
"no-new-require": ["error"],
"no-path-concat": ["error"],
"no-process-exit": ["error"],
"array-bracket-spacing": ["error", "never"],
"block-spacing": ["error", "always"],
"brace-style": ["error"],
"camelcase": ["error"],
"comma-dangle": ["error", "never"],
"comma-spacing": ["error", { "before": false, "after": true }],
"comma-style": ["error", "last"],
"eol-last": ["error"],
"func-call-spacing": ["error", "never"],
"key-spacing": ["error", { "beforeColon": false }],
"keyword-spacing": ["error", { "before": true }],
"new-parens": ["error"],
"no-bitwise": ["error"],
"no-mixed-operators": ["error"],
"no-trailing-spaces": ["error"],
"one-var": ["error", "never"],
"one-var-declaration-per-line": ["error"],
"space-in-parens": ["error", "never"],
"space-infix-ops": ["error"],
"spaced-comment": ["error", "always"],
"curly": ["error"]
}
}
+1
View File
@@ -2,3 +2,4 @@ node_modules
npm-debug.log
.directory
.idea/
out
+148 -62
View File
@@ -1,50 +1,109 @@
"use strict";
'use strict';
var passport = require('passport-strategy');
var LdapAuth = require('ldapauth-fork');
var util = require('util');
/**
* Passport wrapper for ldapauth
*/
var passport = require('passport-strategy'),
LdapAuth = require('ldapauth-fork'),
util = require('util');
/**
* Options callback callback (ie. the callback given if giving a callback
* for options instead of an object)
*
* @callback optionsCallbackCallback
* @param {(Error|undefined)} err - Possible error
* @param {Object} options - Options object
*/
/**
* Options callback
*
* @callback optionsCallback
* @param {Object} req - HTTP request
* @param {optionsCallbackCallback} callback - The callback returning the options
*/
/**
* Verify done callback
*
* @callback verifyDoneCallback
* @param {(Error|undefined)} err - Possible error
* @param {(Object|boolean)} user - The verified user or false if not allowed
* @param {Object} [info] info - Additional info message
*/
/**
* Found LDAP user verify callback
*
* @callback verifyCallback
* @param {Object} user - The user object from LDAP
* @param {verifyDoneCallback} callback - The verify callback
*/
/**
* Found LDAP user verify callback with request
*
* @callback verifyReqCallback
* @param {Object} req - The HTTP request
* @param {Object} user - The user object from LDAP
* @param {verifyDoneCallback} callback - The verify callback
*/
/**
* Add default values to options
*
* @private
* @param {Object} options - Options object
* @returns {Object} The given options with defaults filled
*/
var setDefaults = function(options) {
options.usernameField || (options.usernameField = 'username');
options.passwordField || (options.passwordField = 'password');
return options;
};
/**
* Strategy constructor
* <br>
*
* The LDAP authentication strategy authenticates requests based on the
* credentials submitted through an HTML-based login form.
* <br>
*
* Applications may supply a `verify` callback which accepts `user` object
* and then calls the `done` callback supplying a `user`, which should be set
* to `false` if user is not allowed to authenticate. If an exception occured,
* `err` should be set.
*
* Options:
* - `server` options for ldapauth, see https://github.com/trentm/node-ldapauth
* - `usernameField` field name where the username is found, defaults to _username_
* - `passwordField` field name where the password is found, defaults to _password_
* - `passReqToCallback` when `true`, `req` is the first argument to the verify callback (default: `false`)
* <br>
*
* Options can be also given as function that accepts a callback end calls it
* with error and options arguments. Notice that the callback is executed on
* every authenticate call.
* <br>
*
* Example:
*
* var LdapStrategy = require('passport-ldapauth').Strategy;
* passport.use(new LdapStrategy({
* server: {
* url: 'ldap://localhost:389',
* bindDn: 'cn=root',
* bindCredentials: 'secret',
* searchBase: 'ou=passport-ldapauth',
* searchFilter: '(uid={{username}})',
* reconnect: true
* }
* },
* function(user, done) {
* return cb(null, user);
* }
* ));
* <pre>
* var LdapStrategy = require('passport-ldapauth').Strategy;
* passport.use(new LdapStrategy({
* server: {
* url: 'ldap://localhost:389',
* bindDN: 'cn=root',
* bindCredentials: 'secret',
* searchBase: 'ou=passport-ldapauth',
* searchFilter: '(uid={{username}})',
* reconnect: true
* }
* },
* function(user, done) {
* return cb(null, user);
* }
* ));
* </pre>
* @constructor
* @param {(Object|optionsCallback)} options - Configuration options or options returning function
* @param {(Object)} options.server - [ldapauth-fork options]{@link https://github.com/vesse/node-ldapauth-fork}
* @param {(string)} [options.usernameField=username] - Form field name for username
* @param {(string)} [options.passwordField=password] - Form field name for password
* @param {(boolean)} [options.passReqToCallback=false] - If true, request is passed to verify callback
* @param {(verifyCallback|verifyReqCallback|undefined)} [verify] - User verify callback
*/
var Strategy = function(options, verify) {
// We now accept function as options as well so we cannot assume anymore
@@ -71,23 +130,17 @@ var Strategy = function(options, verify) {
util.inherits(Strategy, passport.Strategy);
/**
* Add default values to options
*
* @param options
* @returns {*}
*/
var setDefaults = function(options) {
options.usernameField || (options.usernameField = 'username');
options.passwordField || (options.passwordField = 'password');
return options;
};
/* eslint-disable */
/**
* Get value for given field from given object. Taken from passport-local,
* copyright 2011-2013 Jared Hanson
*
* @private
* @param {Object} obj - The HTTP request object
* @param {string} field - The field name to look for
* @returns {string|null} - Found value for the field or null
*/
var lookup = function (obj, field) {
var lookup = function(obj, field) {
var i, len, chain, prop;
if (!obj) { return null; }
chain = field.split(']').join('').split('[');
@@ -99,24 +152,36 @@ var lookup = function (obj, field) {
}
return null;
};
/* eslint-enable */
/**
* Verify the outcome of caller verify function - even if authentication (and
* usually authorization) is taken care by LDAP there may be reasons why
* a verify callback is provided, and again reasons why it may reject login
* for a valid user.
*
* @private
* @returns {undefined}
*/
var verify = function() {
// Callback given to user given verify function.
return function(err, user, info) {
if (err) return this.error(err);
if (!user) return this.fail(info);
if (err) {
return this.error(err);
}
if (!user) {
return this.fail(info);
}
return this.success(user, info);
}.bind(this);
};
/**
* Execute failureErrorCallback if provided
*
* @private
* @param {Error} err - The error occurred
* @returns {undefined}
*/
var handleErrorAsFailure = function(err) {
if (typeof this.options.failureErrorCallback === 'function') {
@@ -126,20 +191,19 @@ var handleErrorAsFailure = function(err) {
};
/**
* Options (passed when calling `passport.authenticate()`):
* - `badRequestMessage` flash message for missing username/password
* (default: 'Missing credentials')
* - `invalidCredentials` flash message for InvalidCredentialsError, NoSuchObjectError,
* and /no such user/ LDAP errors
* (default: 'Invalid username/password')
* - `userNotFound` flash message when LDAP returns no error but also no user
* (default: 'Invalid username/password')
* - `constraintViolation` flash message when user account is locked
* (default: 'Exceeded password retry limit, account locked')
* The actual authenticate implementation
*
* @private
* @param {Object} req - The HTTP request
* @param {Object} [options] - Flash messages
* @returns {undefined}
*/
var handleAuthentication = function(req, options) {
var username, password, ldap, errorHandler;
options || (options = {});
var username;
var password;
var ldap;
var errorHandler;
options || (options = {}); // eslint-disable-line no-param-reassign
if (typeof this.options.credentialsLookup === 'function') {
var credentials = this.options.credentialsLookup(req);
@@ -155,7 +219,7 @@ var handleAuthentication = function(req, options) {
}
if (!username || !password) {
return this.fail({message: options.badRequestMessage || 'Missing credentials'}, 400);
return this.fail({ message: options.badRequestMessage || 'Missing credentials' }, 400);
}
errorHandler = this.options.handleErrorsAsFailures === true ? handleErrorAsFailure.bind(this) : this.error.bind(this);
@@ -179,30 +243,34 @@ var handleAuthentication = function(req, options) {
ldap = new LdapAuth(this.options.server);
ldap.on('error', errorHandler);
ldap.authenticate(username, password, function(err, user) {
ldap.close(function(){}); // We don't care about the closing
ldap.close(function(){
// We don't care about the closing
});
if (err) {
// Invalid credentials / user not found are not errors but login failures
if (err.name === 'InvalidCredentialsError' || err.name === 'NoSuchObjectError' || (typeof err === 'string' && err.match(/no such user/i))) {
var message = options.invalidCredentials || 'Invalid username/password';
if(err.message) {
if (err.message) {
var ldapComment = err.message.match(/data ([0-9a-fA-F]*), v[0-9a-fA-F]*/);
if(ldapComment && ldapComment[1]){
if (ldapComment && ldapComment[1]){
message = messages[ldapComment[1]] || messages['default'];
}
}
return this.fail({message: message}, 401);
return this.fail({ message: message }, 401);
}
if (err.name === 'ConstraintViolationError'){
return this.fail({message: options.constraintViolation || 'Exceeded password retry limit, account locked'}, 401);
return this.fail({ message: options.constraintViolation || 'Exceeded password retry limit, account locked' }, 401);
}
// Other errors are (most likely) real errors
return errorHandler(err);
}
if (!user) return this.fail({message: options.userNotFound || 'Invalid username/password'}, 401);
if (!user) {
return this.fail({ message: options.userNotFound || 'Invalid username/password' }, 401);
}
// Execute given verify function
if (this.verify) {
@@ -219,6 +287,22 @@ var handleAuthentication = function(req, options) {
/**
* Authenticate the request coming from a form or such.
*
* @param {Object} req - The HTTP request
* @param {Object} [options] - Authentication options (flash messages). All messages have default values.
* @param {string} [options.badRequestMessage] - Message for missing username/password
* @param {string} [options.invalidCredentials] - Message for InvalidCredentialsError, NoSuchObjectError, and /no such user/ LDAP errors
* @param {string} [options.userNotFound] - Message for user not found
* @param {string} [options.constraintViolation] - Message when account is locked (or other constraint violation)
* @param {string} [options.invalidLogonHours] - Message for Windows AD invalidLogonHours error
* @param {string} [options.invalidWorkstation] - Message for Windows AD invalidWorkstation error
* @param {string} [options.passwordExpired] - Message for Windows AD passwordExpired error
* @param {string} [options.accountDisabled] - Message for Windows AD accountDisabled error
* @param {string} [options.accountDisabled] - Message for Windows AD accountDisabled error
* @param {string} [options.accountExpired] - Message for Windows AD accountExpired error
* @param {string} [options.passwordMustChange] - Message for Windows AD passwordMustChange error
* @param {string} [options.accountLockedOut] - Message for Windows AD accountLockedOut error
* @returns {undefined}
*/
Strategy.prototype.authenticate = function(req, options) {
if ((typeof this.options === 'object') && (!this.getOptions)) {
@@ -226,14 +310,16 @@ Strategy.prototype.authenticate = function(req, options) {
}
var callback = function(err, configuration) {
if (err) return this.fail(err);
if (err) {
return this.fail(err);
}
this.options = setDefaults(configuration);
handleAuthentication.call(this, req, options);
};
// Added functionality: getOptions can accept now up to 2 parameters
if (this.getOptions.length ===1) { // Accepts 1 parameter, backwards compatibility
if (this.getOptions.length === 1) { // Accepts 1 parameter, backwards compatibility
this.getOptions(callback.bind(this));
} else { // Accepts 2 parameters, pass request as well
this.getOptions(req, callback.bind(this));
+15 -10
View File
@@ -30,20 +30,25 @@
"url": "https://github.com/vesse/passport-ldapauth/issues"
},
"dependencies": {
"passport-strategy": "1.x.x",
"ldapauth-fork": "~3.0.0"
"passport-strategy": "^1.0.0",
"ldapauth-fork": "^4.0.0"
},
"devDependencies": {
"basic-auth": "1.1.x",
"body-parser": "1.15.x",
"chai": "3.5.x",
"express": "4.14.x",
"ldapjs": "1.0.x",
"mocha": "3.2.x",
"passport": "0.3.x",
"supertest": "2.0.x"
"basic-auth": "^1.1.0",
"body-parser": "^1.17.2",
"chai": "^4.0.1",
"eslint": "^3.19.0",
"express": "^4.15.3",
"ldapjs": "^1.0.1",
"mocha": "^3.4.2",
"passport": "^0.3.2",
"supertest": "^3.0.0",
"watch": "^1.0.2"
},
"scripts": {
"prepublish": "npm run lint",
"lint": "eslint ./lib",
"lint:watch": "watch 'npm run lint' ./lib --wait 0.5",
"test": "NODE_PATH=lib mocha --reporter spec test/*-test.js"
}
}