Source: controllers/pfilter.js

'use strict';

/**
 * API controller for parameter filtering.
 * @module controllers/usepfilterrs
 * @license MIT
 * @author Kai KRETSCHMANN <kai@kretschmann.consulting>
 */

const log4js = require('log4js');
const logger = log4js.getLogger();
logger.level = process.env.LOGLEVEL || /* istanbul ignore next */ 'warn'; // LCOV_EXCL_LINE

function cleanupString (s) {
  const sNew = s.replace(/[^a-z0-9\-._ ~:+]/gi, '');
  if (sNew !== s) {
    logger.warn('Filtered invalid chars');
  }
  return sNew;
}

function cleanupName (s) {
  const sNew = s.replace(/[^a-z0-9\-.]/gi, '');
  if (sNew !== s) {
    logger.warn('Filtered invalid chars');
  }
  return sNew;
}

function cleanupWord (s) {
  const sNew = s.replace(/[^a-z]/gi, '');
  if (sNew !== s) {
    logger.warn('Filtered invalid chars');
  }
  return sNew;
}

function cleanupStatus (s) {
  if (s.match(/^(register|active|disabled|deleted)$/)) {
    return s;
  } // if
  logger.warn('Filtered invalid status');
  return 'disabled'; // set to default value if in doubt
}

function cleanupNumber (s) {
  const sNew = s.replace(/[^0-9]/g, '');
  if (sNew !== s) {
    logger.warn('Filtered invalid number chars');
  }
  return sNew;
}

function cleanupStringHex (s) {
  const sNew = s.replace(/[^a-f0-9]/gi, '');
  if (sNew !== s) {
    logger.warn('Filtered invalid chars');
  }
  return sNew;
}

/**
 * Filter URL per attribute name and type.
 * @function pfilter
 * @public
 * @param {object} req The web request object
 * @param {object} res The web response object
 * @param {object} next The web next object
 */
module.exports = function (req, res, next) {
  logger.info(`In pfilter: ${req.url}`);
  if (!req.url.startsWith('/v1/')) {
    logger.debug('Ignore non API stuff');
    next();
  } else {
    for (const [key, value] of Object.entries(req.query)) {
      logger.debug(`${key}:${value}`);
      switch (key) {
        case 'count':
        case 'skip':
        case 'page':
        case 'size':
          req.query[key] = cleanupNumber(value);
          break;
        case 'packageName':
        case 'packageArch':
        case 'packageVersion':
        case 'packageFamily':
          req.query[key] = cleanupString(value);
          break;
        case 'packageHash':
          req.query[key] = cleanupStringHex(value);
          break;
        case 'name':
          req.query[key] = cleanupName(value);
          break;
        case 'sort':
        case 'sorters':
        case 'direction':
          req.query[key] = cleanupWord(value);
          break;
        case 'status':
          req.query[key] = cleanupStatus(value);
          break;
        default:
          logger.warn(`Don't know about ${key}`);
          break;
      }
    }
    next();
  }
};