Skip to content

Commit

Permalink
utils: persist values right after selection
Browse files Browse the repository at this point in the history
With this, we can avoid a second run of fields selection,
therefore a sanitizer won't run twice.

Fixes #572, fixes #584
  • Loading branch information
gustavohenke committed Jun 11, 2018
1 parent 1f63999 commit f1f57d5
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 22 deletions.
2 changes: 0 additions & 2 deletions check/check.js
Expand Up @@ -2,7 +2,6 @@ const validator = require('validator');

const runner = require('./runner');
const { isSanitizer, isValidator } = require('../utils/filters');
const persistValues = require('../utils/persist-values');

module.exports = (fields, locations, message) => {
let optional;
Expand All @@ -14,7 +13,6 @@ module.exports = (fields, locations, message) => {
return runner(req, middleware._context).then(errors => {
req._validationContexts = (req._validationContexts || []).concat(middleware._context);
req._validationErrors = (req._validationErrors || []).concat(errors);
persistValues(req, middleware._context);
next();
}, next);
};
Expand Down
2 changes: 0 additions & 2 deletions check/one-of.js
@@ -1,5 +1,4 @@
const _ = require('lodash');
const persistValues = require('../utils/persist-values');
const runner = require('./runner');

module.exports = (validationChains, message) => (req, res, next) => {
Expand Down Expand Up @@ -30,7 +29,6 @@ module.exports = (validationChains, message) => (req, res, next) => {
});
}

contexts.forEach(context => persistValues(req, context));
next();
return results;
}).catch(next);
Expand Down
4 changes: 2 additions & 2 deletions filter/sanitize.js
@@ -1,14 +1,14 @@
const validator = require('validator');

const { isSanitizer } = require('../utils/filters');
const persistValues = require('../utils/persist-values');
const selectFields = require('../utils/select-fields');

module.exports = (fields, locations) => {
const sanitizers = [];
fields = Array.isArray(fields) ? fields : [fields];

const middleware = (req, res, next) => {
persistValues(req, { fields, locations, sanitizers });
selectFields(req, { fields, locations, sanitizers });
next();
};

Expand Down
5 changes: 2 additions & 3 deletions utils/persist-values.js
@@ -1,8 +1,7 @@
const _ = require('lodash');
const selectFields = require('./select-fields');

module.exports = (req, context) => {
selectFields(req, context).filter(instance => {
module.exports = (req, fieldInstances) => {
fieldInstances.filter(instance => {
const initialValue = _.get(req[instance.location], instance.path);
return initialValue !== instance.value;
}).forEach(instance => {
Expand Down
21 changes: 8 additions & 13 deletions utils/persist-values.spec.js
Expand Up @@ -2,20 +2,16 @@ const { expect } = require('chai');
const persistValues = require('./persist-values');

describe('utils: persistValues', () => {
it('persists selected fields back into req', () => {
it('persists a list of fields back into req', () => {
const req = {
query: { foo: ' bar ' },
body: { bar: { baz: ' qux ' } }
};

persistValues(req, {
fields: ['foo', 'bar.baz'],
locations: ['query', 'body'],
sanitizers: [{
options: [],
sanitizer: value => value.trim()
}]
});
persistValues(req, [
{ location: 'query', path: 'foo', value: 'bar' },
{ location: 'body', path: 'bar.baz', value: 'qux' },
]);

expect(req.query.foo).to.equal('bar');
expect(req.body.bar.baz).to.equal('qux');
Expand All @@ -26,10 +22,9 @@ describe('utils: persistValues', () => {
query: {}
};

persistValues(req, {
fields: ['foo'],
locations: ['query']
});
persistValues(req, [
{ location: 'query', path: 'foo', value: undefined },
]);

expect(req.query).not.to.have.key('foo');
});
Expand Down
2 changes: 2 additions & 0 deletions utils/select-fields.js
@@ -1,5 +1,6 @@
const _ = require('lodash');
const formatParamOutput = require('./format-param-output');
const persistValues = require('./persist-values');

module.exports = (req, context, options = {}) => {
let allFields = [];
Expand Down Expand Up @@ -27,6 +28,7 @@ module.exports = (req, context, options = {}) => {
allFields = allFields.concat(instances);
});

persistValues(req, allFields);
return _.uniqWith(allFields, _.isEqual);
};

Expand Down
14 changes: 14 additions & 0 deletions utils/select-fields.spec.js
Expand Up @@ -144,6 +144,20 @@ describe('utils: selectFields', () => {
});
})

it('persists values right after selection', () => {
const req = {
body: { foo: 'a' }
};

selectFields(req, {
fields: ['foo'],
locations: ['body'],
sanitizers: [{ sanitizer: value => value.toUpperCase(), options: [] }]
});

expect(req.body.foo).to.equal('A');
});

describe('sanitization', () => {
it('runs on the selected values', () => {
const req = {
Expand Down

0 comments on commit f1f57d5

Please sign in to comment.