All files / bintra/controllers pfilter.js

100% Statements 50/50
100% Branches 31/31
100% Functions 7/7
100% Lines 50/50

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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114                  1x 1x 1x     58x 58x 1x   58x       4x 4x 1x   4x       7x 7x 2x   7x       2x 1x   1x 1x       9x 9x 2x   9x       13x 13x 1x   13x                     1x 84x 84x 1x 1x   83x 94x 94x         9x 9x           58x 58x   13x 13x   4x 4x       7x 7x   2x 2x   1x 1x     83x      
'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':
        case 'packageSubFamily':
          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();
  }
};