ah-tdp-auth-plugin

2.0.4 • Public • Published

ah-tdp-auth-plugin

Version

Master: v2.0.4 Travis CI build status icon Code Climate Coverage Status Dependency Status

Semver

This project aims to maintain the semver version numbering scheme.

Changelog

See the changelog file

Overview

A fast, comprehensive, secure authentication plugin for actionHero with a MongoDB storage layer.

ah-tdp-auth-plugin is designed specifically for use with the actionHero API framework and thus is unlikely to work directly with any other application. You're welcome to fork and modify of course if that is of interest of course.

Features

  • Configurable, cryptographically strong password hashing with configurable per-user salting. Configurable options are:
    • Cipher (e.g. SHA256)
    • Digest (e.g. base64)
    • Salt length
  • Strict user input filtering on all fields in all methods
  • Configurable complexity requirements on all critical authentication parameters (with sensible defaults) e.g.
    • Required/optional fields
    • Min and max length conditions
    • Must-contain conditions (you may specify one or more regexs)
    • Disallowed character checking (e.g. non-printables as default setting)
    • Predefined value-set restriction (like SQL enumerated fields)
    • Allowed data type constraints e.g. String, Number etc.
  • Configurable password expiry periods
  • Includes user role (designed to be used with an ACL such as my own TDP-AH-ACL)
  • Configurable, automatic (on initialisation) index creation with constraints e.g. unique, dedupe, creation in background etc.
  • Optional soft deletion of user accounts (to enable post-deletion lookups for historical records)
  • Fast - most operations complete in a low, single-digit number of milliseconds on a moderately powered system
  • Asynchronous operation throughout
  • Included unit tests, automatically run via Travis-CI
  • Included default actions for all public methods
  • Included initialiser
  • MongoDB back end
    • Optional MongoDB authentication (use it!)
    • Configurable MongoDB server address/socket and port
    • Configurable database and collection names

Requirements

Prerequisite since it's the plugin host

Production requirements

Development/test requirements

Installation

Installation is relatively simple and is simplest using npm (optionally, suffix with --save as shown below to add the package to the local package.json file):

# Install actionhero (skip this if you have already got it installed) 
npm install actionhero
 
# Generate a skeleton actionhero project 
./node_modules/.bin/actionhero generate
 
# Install ah-tdp-auth-plugin 
npm install ah-tdp-auth-plugin --save

Then you'll need to edit the actionhero config file, config/api.js and add the plugin name into the plugins array.

After that, you can start your API server using npm start.

No doubt you'll want to change lots more things but the above is a generic set of instructions.

Usage

This module is an actionhero plugin so it conforms to the base requirements, this means it provides:

  • Actions
  • An initialiser
  • An editable, userland config file (which is actionhero 'environment' (development, production etc.) aware) which will appear as <project root>/config/plugins/AHTDPAuthPlugin.js assuming the postinstall NPM script worked properly
  • The core module itself

Configuration

You should edit the userland config file as required, this is where you can customise the module to fit your project requirements. This file will not be replaced by module updates so you need to manually keep it up to date, at least until I create some automated method.

For detailed explanation of the fields, check the userland or default config file comments.

Configuration file: environments

Configuration options can be defined for all or (overridden) for individual environments using the following structure:

exports.default=
{
    AHTDPAuthPlugin: function(api)
    {
        return {
            ...
        }
    }
}
 
exports.production=
{
    AHTDPAuthPlugin: function(api)
    {
        return {
            ...
        }
    }
}
 
...
 

This structure is as per the common actionhero configuration model. The environment is set via a environment variable (on *nix systems this is NODE_ENV) which override the base/default options in exports.defaults{}. So you should put common (environment agnostic/independent) configuration options in the exports.defaults{} section and then override/augment those with any environment-specific options as required.

Configuration file: fields

You can configure the fields you want to be able to use with this module by adding them to the configuration file. You should not remove any of the default fields as they are required by the processing logic (though you can remove them from user-level output - see below).

Configuration file: field constraints

This module allows for several complexity and content requirements to be configured for each field. A full example of the current fields is shown below, using the userID field defaults as an example:

userID:
{
    required:true, // Is the field required?
    allowedTypes:["string"], // Allowed data types (currently only values returnable from typeof() are supported) (array, leave empty or omit to allow any data type)
    disallowedCharsRegex:/[^\x20-\x7e]/, // Disallowed chars (regex)
    mustContainCharsRegexArray:[/[a-z]/,/[A-Z]/], // Array of regex's which MUST be present in the value supplied (array of regex's)
    minLength:8, // Min length (chars) of passwords to allow (int)
    maxLength:null, // Max length (chars) of passwords to allow (int)
    defaultValue:null, // Default value if none is supplied, can be a function which must return one value, that being the defaultValue you want to set if none is supplied
    removeFromInput:false, // Remove from user input before processing (you normally should not edit this) (boolean)
    removeFromOutput:false // Remove from output before returning from functions. Ensure any sensitive fields (e.g. passwords, salts etc.) are removed (boolean)
}

Actions

A default set of actions are provided. You can choose to use or replace these as you see fit.

The default actions are in /actions/AHTDPAuth in this plugin module. The default actions are all "namespaced" via the AHTDPAuth prefix (to help avoid clashes) and thus from the front end you'd call them as such e.g. for the authenticateUser action, you'd do:

//....
client.action("ah-tdp-auth-plugin/authenticateUser", {u: "someUser", p:"somePassword"}, function(response)
{
    console.log("Server output is:");
    console.dir(response);
});

Constructor

The constructor is very simple and since the module is function-scoped, it requires the 'new' syntax in the constructor to instantiate a new instance e.g.:

var AHTDPAuthPlugin=require("ah-tdp-auth-plugin");
var auth=new AHTDPAuthPlugin(api); // (where api is the actionhero api instance)
...

The module will self-initialise, using the actionhero environment-specific config options. A successful initialisation results in an object being returned

Public methods

General principals

All public methods conform to the below principals:

  • They are asynchronous and thus receive a callback function as the last argument
  • They will filter all user input and output based on youre configured options in userObjectProperties
  • They will (in async mode) return two values, error and result, where:
    • error is a string, object or array if an error occurred, null otherwise
    • result is a string, object, array, number etc. on success, null otherwise
  • They will never throw errors, instead they will return accordingly
  • All arguments are required

createUser(userObjectToCreate, callback)

Create user method.

Arguments

userObjectToCreate (object)

An object containing properties commensurate with the configured userObjectProperties. The validity of the object will be checked prior to processing.

callback (function)

The callback function to execute on completion, this will receive the two standard callback arguments, error and result.

Returns (callback arguments)

  • error - a string, object or array if an error occurred, null otherwise
  • result - on success is the created, complete (including any fields not supplied but set automaticaly via userObjectProperties.<property>.defaultValue) user object, null otherwise.

authenticateUser(userID, password, callback)

Authenticate user method.

Arguments

userID (string)

The userID for the account to be authenticated.

password (string)

The password for the account to be authenticated.

callback (function)

The callback function to execute on completion, this will receive the two standard callback arguments, error and result.

Returns (callback arguments)

  • error - a string, object or array if an error occurred, null otherwise
  • result - on success is the user object for the authenticated user, null otherwise.

getUser(where, options, callback)

Get user method, retrieves one or more user objects for users matching the where argumnent constraints.

Arguments

where (object)

An object containing zero or more user object constraints (e.g. {dateDeleted:null} would fetch all non soft-deleted users).

options (string)

Options for the MongoDB query to be run e.g. sort, limit etc. For more information see XXXXXXX

callback (function)

The callback function to execute on completion, this will receive the two standard callback arguments, error and result.

Returns (callback arguments)

  • error - a string, object or array if an error occurred, null otherwise
  • result - on success is an array of the matching user objects, null otherwise.

updateUser(userID, updatedUserObject, callback)

Update user method. It is noteworthy that this method merges data onto the existing user object in the database - see below for details.

Arguments

userID (string)

The userID for the account to be authenticated.

updatedUserObject (object)

An object containing properties commensurate with the configured userObjectProperties with which to update the stored user object. The validity of the object will be checked prior to processing. The object provided will be merged with the existing object (to allow partial updates) so you should nullify (etc.) relevant properties as required.

callback (function)

The callback function to execute on completion, this will receive the two standard callback arguments, error and result.

Returns (callback arguments)

  • error - a string, object or array if an error occurred, null otherwise
  • result - on success is the updated user object (merged with the previously existing user object), null otherwise.

deleteUserFn(userID, callback)

Delete user method. This method obeys the config option config.options.softDelete (boolean) and thus will soft delete (mark users as delete but not remove them from the database) if that option is true.

Arguments

userID (string)

The userID for the account to be deleted.

callback (function)

The callback function to execute on completion, this will receive the two standard callback arguments, error and result.

Returns (callback arguments)

  • error - a string, object or array if an error occurred, null otherwise
  • result - on success is the deleted user object (including the soft delete field dateDeleted if config.options.softDelete is true), null otherwise.

verifyUserObjectProperty(propertyName, propertyValue, callback)

Delete user method. This method obeys the config option config.options.softDelete (boolean) and thus will soft delete (mark users as delete but not remove them from the database) if that option is true.

Arguments

propertyName (string)

The property name to verify. Note that this must be defined in config.userObjectProperties, otherwise an error will occur (see below for details of returned values).

propertyValue (mixed)

The property value to verify against the defined constraints in the relevant field in config.userObjectProperties.

callback (function)

The callback function to execute on completion, this will receive the two standard callback arguments, error and result.

Returns (callback arguments)

  • error - a string, object or array if an error occurred, null otherwise
  • result - true on success, null otherwise.

verifyUserObject(userObject, ignorePropertiesArray, callback)

Delete user method. This method obeys the config option config.options.softDelete (boolean) and thus will soft delete (mark users as delete but not remove them from the database) if that option is true.

Arguments

userObject (object)

The user object to verify against the defined constraints in config.userObjectProperties.

ignorePropertiesArray (array)

An array, consisting of any user object properties which should be excluded from the verification.

callback (function)

The callback function to execute on completion, this will receive the two standard callback arguments, error and result.

Returns (callback arguments)

  • error - a string, object or array if an error occurred, null otherwise
  • result - true on success, null otherwise.

To do/roadmap

  • FRONT END
    • PROB TEMPLATES ETC. VIA ANOTHER PLUGIN TO ALLOW MULTIPLE TEMPLATE ENGINES E.G. HANDLEBARS, MUSTACHE ETC.
      • THESE WOULD NEED AN INITIALISER WHICH COULD:
        • ADD TO THE PUBLIC DIR TO ALLOW THE FILES TO BE USED
        • MINIFY FILES
        • ETC.
    • PROB PROVIDE (PUBLIC) FIELD GENERATOR METHOD ON THIS LIB:
      • NEED TO ADD FIELDS TO CONFIG TO ACCOMODATE E.G:
        • PARAM NAME
        • FIELD TYPE
        • ORDER (IN TEMPLATE)
  • Vulnerability testing!
  • Ensure indexes are optimal
  • Allow connection to MongoDB replicasets

Tests

Tests currently run in a raw mode (simply running scripts which use process.exit() and the relevant exit code) and are run via Travis CI.

License

ah-tdp-auth-plugin is issued under a Creative Commons attribution share-alike license. This means you can share and adapt the code provided you attribute the original author(s) and you share your resulting source code. If, for some specific reason you need to use this library under a different license then please contact me and i'll see what I can do - though I should mention that I am committed to all my code being open-source so closed licenses will almost certainly not be possible.

Package Sidebar

Install

npm i ah-tdp-auth-plugin

Weekly Downloads

6

Version

2.0.4

License

CC-BY-SA-3.0

Last publish

Collaborators

  • tdp_org