All files / src/hooks hash-password.js

97.62% Statements 41/42
92.59% Branches 25/27
100% Functions 7/7
97.62% Lines 41/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 761x 1x 1x   1x   11x 11x 11x 1x     10x 10x   10x   10x   10x 10x   10x       10x 1x     9x 1x 1x     8x     8x 3x 6x   5x 4x         8x 1x 1x     7x 3x   3x 6x 6x 6x       3x 3x       4x 4x 4x 4x        
import hasher from '../utils/hash';
import merge from 'lodash.merge';
import Debug from 'debug';
 
const debug = Debug('feathers-authentication-local:hooks:hash-password');
 
export default function hashPassword (options = {}) {
  return function (hook) {
    if (hook.type !== 'before') {
      return Promise.reject(new Error(`The 'hashPassword' hook should only be used as a 'before' hook.`));
    }
 
    const app = hook.app;
    const authOptions = app.get('authentication') || {};
 
    options = merge({ passwordField: 'password' }, authOptions.local, options);
 
    debug('Running hashPassword hook with options:', options);
 
    const field = options.passwordField;
    const hashPw = options.hash || hasher;
 
    Iif (typeof field !== 'string') {
      return Promise.reject(new Error(`You must provide a 'passwordField' in your authentication configuration or pass one explicitly`));
    }
 
    if (typeof hashPw !== 'function') {
      return Promise.reject(new Error(`'hash' must be a function that takes a password and returns Promise that resolves with a hashed password.`));
    }
 
    if (hook.data === undefined) {
      debug(`hook.data is undefined. Skipping hashPassword hook.`);
      return Promise.resolve(hook);
    }
 
    let data;
 
    // make sure we actually have password fields
    if (Array.isArray(hook.data)) {
      data = hook.data.filter(item => {
        return item.hasOwnProperty(field);
      });
    } else if (hook.data[field]) {
      data = hook.data;
    }
 
    // If the data doesn't have a password field
    // then don't attempt to hash it.
    if (data === undefined || (Array.isArray(data) && !data.length)) {
      debug(`'${field}' field is missing. Skipping hashPassword hook.`);
      return Promise.resolve(hook);
    }
 
    if (Array.isArray(data)) {
      debug(`Hashing passwords.`);
 
      return Promise.all(data.map(item => {
        return hashPw(item[field]).then(hashedPassword => {
          item[field] = hashedPassword;
          return item;
        });
      }))
      .then(results => {
        hook.data = results;
        return Promise.resolve(hook);
      });
    }
 
    debug(`Hashing password.`);
    return hashPw(data[field]).then(hashedPassword => {
      hook.data[field] = hashedPassword;
      return Promise.resolve(hook);
    });
  };
}