All files / src reset-password.js

97.44% Statements 38/39
66.67% Branches 4/6
100% Functions 5/5
97.44% Lines 38/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 921x 1x 1x 1x 1x 1x 1x 1x 1x   1x   1x           28x   28x 20x       11x 11x   9x 6x       37x 37x 37x 37x     37x 28x 28x 9x 9x             37x 37x   26x 26x         21x             26x 26x   21x                       26x             26x 26x    
const errors = require('@feathersjs/errors');
const makeDebug = require('debug');
const comparePasswords = require('./helpers/compare-passwords');
const deconstructId = require('./helpers/deconstruct-id');
const ensureObjPropsValid = require('./helpers/ensure-obj-props-valid');
const ensureValuesAreStrings = require('./helpers/ensure-values-are-strings');
const getUserData = require('./helpers/get-user-data');
const hashPassword = require('./helpers/hash-password');
const notifier = require('./helpers/notifier');
 
const debug = makeDebug('authLocalMgnt:resetPassword');
 
module.exports = {
  resetPwdWithLongToken,
  resetPwdWithShortToken
};
 
async function resetPwdWithLongToken (options, resetToken, password, field) {
  ensureValuesAreStrings(resetToken, password);
 
  const result = await resetPassword(options, { resetToken }, { resetToken }, password, field);
  return result;
}
 
async function resetPwdWithShortToken (options, resetShortToken, identifyUser, password, field) {
  ensureValuesAreStrings(resetShortToken, password);
  ensureObjPropsValid(identifyUser, options.identifyUserProps);
 
  const result = await resetPassword(options, identifyUser, { resetShortToken }, password, field);
  return result;
}
 
async function resetPassword (options, query, tokens, password, field) {
  debug('resetPassword', query, tokens, password);
  const usersService = options.app.service(options.service);
  const usersServiceIdName = usersService.id;
  const promises = [];
  let users;
 
  if (tokens.resetToken) {
    let id = deconstructId(tokens.resetToken);
    users = await usersService.get(id);
  } else Eif (tokens.resetShortToken) {
    users = await usersService.find({ query });
  } else {
    throw new errors.BadRequest('resetToken and resetShortToken are missing. (authLocalMgnt)', {
      errors: { $className: 'missingToken' }
    });
  }
 
  const checkProps = options.skipIsVerifiedCheck ? ['resetNotExpired'] : ['resetNotExpired', 'isVerified'];
  const user1 = getUserData(users, checkProps);
 
  Object.keys(tokens).forEach(key => {
    promises.push(
      comparePasswords(
        tokens[key],
        user1[key],
        () =>
          new errors.BadRequest('Reset Token is incorrect. (authLocalMgnt)', {
            errors: { $className: 'incorrectToken' }
          })
      )
    );
  });
 
  try {
    await Promise.all(promises);
  } catch (err) {
    await usersService.patch(user1[usersServiceIdName], {
      resetToken: null,
      resetShortToken: null,
      resetExpires: null
    });
    /*
    new errors.BadRequest('Invalid token. Get for a new one. (authLocalMgnt)', {
      errors: { $className: 'invalidToken' }
    });
    */
  }
 
  const user2 = await usersService.patch(user1[usersServiceIdName], {
    password: await hashPassword(options.app, password, field),
    resetToken: null,
    resetShortToken: null,
    resetExpires: null
  });
 
  const user3 = await notifier(options.notifier, 'resetPwd', user2);
  return options.sanitizeUserForClient(user3);
}