{"size": 2636, "ext": "js", "max_stars_repo_path": "lib/index.js", "max_stars_repo_name": "umrysh/feathers-permissions", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "lib/index.js", "max_issues_repo_name": "umrysh/feathers-permissions", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "lib/index.js", "max_forks_repo_name": "umrysh/feathers-permissions", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 30.6511627907, "max_line_length": 164, "alphanum_fraction": 0.6297420334}
const { Forbidden } = require('@feathersjs/errors');
const get = require('lodash/get');

const debug = require('debug')('feathers-permissions');

module.exports = function checkPermissions (options = {}) {
  const {
    entity: entityName = 'user',
    field = 'permissions',
    error = true
  } = options;
  const permissions = options.permissions || options.roles;

  if (!Array.isArray(permissions) && typeof permissions !== 'function') {
    throw new Error('\'roles\' option for feathers-permissions hook must be an array or a function');
  }

  return async context => {
    const { params, type, method } = context;
    const currentPermissions = await Promise.resolve(typeof permissions === 'function' ? permissions(context) : permissions);

    if (type !== 'before') {
      throw new Error('The feathers-permissions hook should only be used as a \'before\' hook.');
    }

    debug('Running checkPermissions hook with options:', { entityName, field, roles: permissions });

    const entity = context.params[entityName];

    if (!entity) {
      debug(`hook.params.${entityName} does not exist. If you were expecting it to be defined check your hook order and your idField options in your auth config.`);

      if (params.provider) {
        throw new Forbidden('You do not have the correct permissions (invalid permission entity).');
      }

      return context;
    }

    // Normalize permissions. They can either be a comma separated string or an array.
    let value = get(entity, field, []);
    if(typeof value === 'number'){
        value = value.toString();
    }
    let permissionList = typeof value === 'string'
      ? value.split(',').map(current => current.trim()) : value;


    if (permissionList.length === 0){
      // check the default value as well
      value = get(entity, 'permissions', []);
      if(typeof value === 'number'){
          value = value.toString();
      }
      permissionList = typeof value === 'string'
        ? value.split(',').map(current => current.trim()) : value;
    }
    
    const requiredPermissions = [
      '*',
      `*:${method}`
    ];

    currentPermissions.forEach(permission => requiredPermissions.push(
      `${permission}`,
      `${permission}:*`,
      `${permission}:${method}`
    ));

    debug('Required Permissions', requiredPermissions);

    const permitted = permissionList.some(current => requiredPermissions.includes(current));

    if (error !== false && !permitted) {
      throw new Forbidden('You do not have the correct permissions.');
    }

    context.params = {
      permitted,
      ...params
    };

    return context;
  };
};
