{"size": 2400, "ext": "js", "max_stars_repo_path": "forms-flow-forms/src/actions/fields/password.js", "max_stars_repo_name": "andrepestana-aot/forms-flow-ai", "max_stars_repo_stars_event_min_datetime": "2020-04-16T20:26:18.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-30T12:39:50.000Z", "max_issues_repo_path": "forms-flow-forms/src/actions/fields/password.js", "max_issues_repo_name": "andrepestana-aot/forms-flow-ai", "max_issues_repo_issues_event_min_datetime": "2020-06-05T21:30:27.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-30T04:53:25.000Z", "max_forks_repo_path": "forms-flow-forms/src/actions/fields/password.js", "max_forks_repo_name": "andrepestana-aot/forms-flow-ai", "max_forks_repo_forks_event_min_datetime": "2020-04-15T18:54:51.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-29T04:58:49.000Z"}
{"max_stars_count": 132, "max_issues_count": 102, "max_forks_count": 91, "avg_line_length": 30.3797468354, "max_line_length": 113, "alphanum_fraction": 0.4583333333}
'use strict';

const _ = require('lodash');

module.exports = (formio) => {
  const hook = require('../../util/hook')(formio);

  const encryptField = (component, data, next) => {
    formio.encrypt(_.get(data, component.key), (err, hash) => {
      if (err) {
        return next(err);
      }

      _.set(data, component.key, hash);
      next();
    });
  };

  return async (component, data, handler, action, {validation, path, req, res}) => {
    switch (handler) {
      case 'beforeGet':
        req.modelQuery.select(`-data.${path}${component.key}`);
        break;
      case 'beforePut':
        // Only perform password encryption after validation has occurred.
        if (validation) {
          return new Promise((resolve, reject) => {
            if (_.has(data, component.key)) {
              encryptField(component, data, (err) => {
                if (err) {
                  return reject(err);
                }
                // Since the password was changed, invalidate all user tokens.
                hook.alter('invalidateTokens', req, res, (err) => {
                  if (err) {
                    return reject(err);
                  }

                  if (!req.skipTokensInvalidation) {
                    _.set(req.body, 'metadata.jwtIssuedAfter', req.tokenIssued || Math.trunc(Date.now() / 1000));
                  }
                  resolve();
                });
              });
            }
            else {
              // If there is no password provided.
              // Load the current submission.
              formio.cache.loadCurrentSubmission(req, function cacheResults(err, submission) {
                if (err) {
                  return reject(err);
                }
                if (!submission) {
                  return reject(new Error('No submission found.'));
                }

                _.set(data, component.key, _.get(submission.data, path));
                return resolve();
              });
            }
          });
        }
        break;
      case 'beforePost':
        if (validation && _.has(data, component.key)) {
          return new Promise((resolve, reject) => {
            encryptField(component, data, (err) => {
              if (err) {
                return reject(err);
              }
              return resolve();
            });
          });
        }
        break;
    }
  };
};
