Browse Source

sanitizeAll validates req.query parameters, export async runAllChecks function

pull/942/head
Lily He 7 years ago
parent
commit
af906c05a8
  1. 51
      sanitizer/sanitizeAll.js
  2. 172
      test/unit/sanitizer/sanitizeAll.js

51
sanitizer/sanitizeAll.js

@ -1,3 +1,5 @@
const async = require('async');
function sanitize( req, sanitizers, cb ){ function sanitize( req, sanitizers, cb ){
// init an object to store clean (sanitized) input parameters if not initialized // init an object to store clean (sanitized) input parameters if not initialized
req.clean = req.clean || {}; req.clean = req.clean || {};
@ -8,10 +10,10 @@ function sanitize( req, sanitizers, cb ){
// source of input parameters // source of input parameters
// (in this case from the GET querystring params) // (in this case from the GET querystring params)
var params = req.query || {}; const params = req.query || {};
for (var s in sanitizers) { for (var s in sanitizers) {
var sanity = sanitizers[s]( params, req.clean ); var sanity = sanitizers[s].sanitize( params, req.clean );
// if errors occurred then set them // if errors occurred then set them
// on the req object. // on the req object.
@ -25,10 +27,51 @@ function sanitize( req, sanitizers, cb ){
req.warnings = req.warnings.concat( sanity.warnings ); req.warnings = req.warnings.concat( sanity.warnings );
} }
} }
return cb( undefined, req.clean );
}
// Adds to schemaKeys every acceptable parameter passed through API call
function checkParameters(req, sanitizers, cb) {
// source of input parameters
// (in this case from the GET querystring params)
const params = req.query || {};
const goodParameters = {};
for (var s in sanitizers) {
// @todo remove these args, they do not need to be passed out // checks if there is a function that returns valid params
if (typeof sanitizers[s].expected === 'function'){
/** func returns {array} ex: [{ name: 'text' }, { name: 'parsed_text' }] */
for (let t in sanitizers[s].expected()) {
/** {object} prop */
const prop = sanitizers[s].expected()[t];
if (prop.hasOwnProperty('name')){
// adds name of valid parameter
goodParameters[prop.name] = prop.name;
}
}
}
}
// If there are any unexpected parameters, add a warning to messages
for (let p in params) {
if (!goodParameters.hasOwnProperty(p)){
req.warnings = req.warnings.concat('Invalid Parameter: ' + p);
}
}
return cb( undefined, req.clean ); return cb( undefined, req.clean );
} }
// runs both sanitize and checkParameters functions in async parallel
function runAllChecks (req, sanitizers, cb) {
async.parallel([
sanitize.bind(null, req, sanitizers),
checkParameters.bind(null, req, sanitizers)
], cb);
}
// export function // export function
module.exports = sanitize; module.exports = {
sanitize: sanitize,
checkParameters: checkParameters,
runAllChecks: runAllChecks
};

172
test/unit/sanitizer/sanitizeAll.js

@ -1,26 +1,31 @@
var sanitizeAll = require('../../../sanitizer/sanitizeAll'); var sanitizeAll = require('../../../sanitizer/sanitizeAll');
const Joi = require('joi');
module.exports.tests = {}; module.exports.tests = {};
module.exports.tests.all = function(test, common) { module.exports.tests.all = function(test, common) {
test('req.clean/errors/warnings should be initialized when they are not', function(t) { test('req.clean/errors/warnings should be initialized when they are not', function(t) {
var req = {}; var req = {};
var sanitizers = [ var sanitizers = {
function() { 'first': {
req.clean.a = 'first sanitizer'; sanitize: function(){
return { req.clean.a = 'first sanitizer';
errors: ['error 1', 'error 2'], return {
warnings: ['warning 1', 'warning 2'] errors: ['error 1', 'error 2'],
}; warnings: ['warning 1', 'warning 2']
};
}
}, },
function() { 'second': {
req.clean.b = 'second sanitizer'; sanitize: function() {
return { req.clean.b = 'second sanitizer';
errors: ['error 3'], return {
warnings: ['warning 3'] errors: ['error 3'],
}; warnings: ['warning 3']
};
}
} }
]; };
var expected_req = { var expected_req = {
clean: { clean: {
@ -31,7 +36,7 @@ module.exports.tests.all = function(test, common) {
warnings: ['warning 1', 'warning 2', 'warning 3'] warnings: ['warning 1', 'warning 2', 'warning 3']
}; };
sanitizeAll(req, sanitizers, function(){ sanitizeAll.sanitize(req, sanitizers, function (){
t.deepEquals(req, expected_req); t.deepEquals(req, expected_req);
t.end(); t.end();
}); });
@ -47,22 +52,26 @@ module.exports.tests.all = function(test, common) {
warnings: ['pre-existing warning'] warnings: ['pre-existing warning']
}; };
var sanitizers = [ var sanitizers = {
function() { 'first': {
req.clean.a = 'first sanitizer'; sanitize: function(){
return { req.clean.a = 'first sanitizer';
errors: ['error 1', 'error 2'], return {
warnings: ['warning 1', 'warning 2'] errors: ['error 1', 'error 2'],
}; warnings: ['warning 1', 'warning 2']
};
}
}, },
function() { 'second': {
req.clean.b = 'second sanitizer'; sanitize: function() {
return { req.clean.b = 'second sanitizer';
errors: ['error 3'], return {
warnings: ['warning 3'] errors: ['error 3'],
}; warnings: ['warning 3']
};
}
} }
]; };
var expected_req = { var expected_req = {
clean: { clean: {
@ -74,7 +83,7 @@ module.exports.tests.all = function(test, common) {
warnings: ['pre-existing warning', 'warning 1', 'warning 2', 'warning 3'] warnings: ['pre-existing warning', 'warning 1', 'warning 2', 'warning 3']
}; };
sanitizeAll(req, sanitizers, function(){ sanitizeAll.sanitize(req, sanitizers, function () {
t.deepEquals(req, expected_req); t.deepEquals(req, expected_req);
t.end(); t.end();
}); });
@ -84,33 +93,35 @@ module.exports.tests.all = function(test, common) {
test('req.query should be passed to individual sanitizers when available', function(t) { test('req.query should be passed to individual sanitizers when available', function(t) {
var req = { var req = {
query: { query: {
value: 'query value' value: 'query'
} }
}; };
var sanitizers = [ var sanitizers = {
function(params) { 'first': {
req.clean.query = params; sanitize: function(params) {
return { req.clean.query = params;
errors: [], return {
warnings: [] errors: [],
}; warnings: []
};
}
} }
]; };
var expected_req = { var expected_req = {
query: { query: {
value: 'query value' value: 'query'
}, },
clean: { clean: {
query: { query: {
value: 'query value' value: 'query'
} }
}, },
errors: [], errors: [],
warnings: [] warnings: []
}; };
sanitizeAll(req, sanitizers, function(){ sanitizeAll.sanitize(req, sanitizers, function () {
t.deepEquals(req, expected_req); t.deepEquals(req, expected_req);
t.end(); t.end();
}); });
@ -119,18 +130,20 @@ module.exports.tests.all = function(test, common) {
test('an empty object should be passed to individual sanitizers when req.query is unavailable', function(t) { test('an empty object should be passed to individual sanitizers when req.query is unavailable', function(t) {
var req = {}; var req = {};
var sanitizers = [ var sanitizers = {
function(params) { 'first': {
if (Object.keys(params).length === 0) { sanitize: function(params) {
req.clean.empty_object_was_passed = true; if (Object.keys(params).length === 0) {
req.clean.empty_object_was_passed = true;
}
return {
errors: [],
warnings: []
};
} }
return {
errors: [],
warnings: []
};
} }
]; };
var expected_req = { var expected_req = {
clean: { clean: {
@ -140,13 +153,66 @@ module.exports.tests.all = function(test, common) {
warnings: [] warnings: []
}; };
sanitizeAll(req, sanitizers, function(){ sanitizeAll.sanitize(req, sanitizers, function () {
t.deepEquals(req, expected_req); t.deepEquals(req, expected_req);
t.end(); t.end();
}); });
}); });
test('unexpected parameters should throw warning', function(t) {
var req = {
query: {
unknown_value: 'query value'
},
errors: [],
warnings: []
};
var sanitizers = {
'first': {
expected: function _expected () {
// add value as a valid parameter for joi
return [{
name: 'value'
}];
}
}
};
sanitizeAll.checkParameters(req, sanitizers, function () {
t.equals(req.errors.length, 0);
t.deepEquals(req.warnings[0], 'Invalid Parameter: unknown_value');
t.end();
});
});
test('expected parameters should not throw warning', function(t) {
var req = {
query: {
value: 'query value'
},
errors: [],
warnings: []
};
var sanitizers = {
'first': {
expected: function _expected () {
// add value as a valid parameter for joi
return [{
name: 'value'
}];
}
}
};
sanitizeAll.checkParameters(req, sanitizers, function () {
t.equals(req.errors.length, 0);
t.equals(req.warnings.length, 0);
t.end();
});
});
}; };
module.exports.all = function (tape, common) { module.exports.all = function (tape, common) {

Loading…
Cancel
Save