Skip to content

Commit

Permalink
fix(Sanitize): Remove non writable property on Joi schema (#140)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebelga committed Dec 29, 2018
1 parent 7f89cbc commit 4ba1ce6
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
3 changes: 2 additions & 1 deletion lib/helpers/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ const validate = (entityData, schema, entityKind) => {
// We leave the validation to Joi
const joiOptions = schema.options.joi.options || {};
joiOptions.stripUnknown = {}.hasOwnProperty.call(joiOptions, 'stripUnknown')
? joiOptions.stripUnknown : schema.options.explicitOnly !== false;
? joiOptions.stripUnknown
: schema.options.explicitOnly !== false;
return schema._joi.validate(entityData, joiOptions);
}

Expand Down
22 changes: 16 additions & 6 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,30 @@ const sanitize = (data, schema, options = { disabled: [] }) => {
return null;
}

if (!is.undef(schema._joi)) {
const { value } = schema._joi.validate(data);
return value;
const isJoiSchema = !is.undef(schema._joi);

let sanitized;
let joiOptions;
if (isJoiSchema) {
sanitized = schema._joi.validate(data).value;
joiOptions = schema.options.joi.options || {};
} else {
sanitized = Object.assign({}, data);
}

const sanitized = Object.assign({}, data);
const isSchemaExplicitOnly = schema.options.explicitOnly !== false;
const isSchemaExplicitOnly = isJoiSchema
? !joiOptions.allowUnknown
: schema.options.explicitOnly !== false;

const isWriteDisabled = options.disabled.includes('write');
let schemaHasProperty;
let isPropWritable;

Object.keys(data).forEach((k) => {
schemaHasProperty = {}.hasOwnProperty.call(schema.paths, k);
isPropWritable = schemaHasProperty && schema.paths[k].write !== false;
isPropWritable = schemaHasProperty
? schema.paths[k].write !== false
: true;

if ((isSchemaExplicitOnly && !schemaHasProperty) || (!isPropWritable && !isWriteDisabled)) {
delete sanitized[k];
Expand Down
6 changes: 3 additions & 3 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,15 @@ function buildJoiSchema(schema, joiConfig) {
}

const hasExtra = is.object(joiConfig) && is.object(joiConfig.extra);
const rawJoiSchema = {};
const joiKeys = {};

Object.keys(schema).forEach((k) => {
if ({}.hasOwnProperty.call(schema[k], 'joi')) {
rawJoiSchema[k] = schema[k].joi;
joiKeys[k] = schema[k].joi;
}
});

let joiSchema = Joi.object(rawJoiSchema);
let joiSchema = Joi.object().keys(joiKeys);
let args;

if (hasExtra) {
Expand Down
18 changes: 15 additions & 3 deletions test/model-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,27 @@ describe('Model', () => {
expect(data2).not.equal(data);
});

it('should sanitize with Joi.strip()', () => {
it('should remove not writable & unknown props in Joi schema', () => {
schema = new Schema({
createdOn: { joi: Joi.strip() },
createdOn: { joi: Joi.date(), write: false },
}, { joi: true });
ModelInstance = gstore.model('BlogJoi', schema, gstore);

const entityData = ModelInstance.sanitize({ createdOn: 'abc' });
const entityData = ModelInstance.sanitize({ createdOn: Date.now(), unknown: 123 });

assert.isUndefined(entityData.createdOn);
assert.isUndefined(entityData.unknown);
});

it('should *not* remove unknown props in Joi schema', () => {
schema = new Schema({
createdOn: { joi: Joi.date(), write: false },
}, { joi: { options: { allowUnknown: true } } });
ModelInstance = gstore.model('BlogJoi', schema, gstore);

const entityData = ModelInstance.sanitize({ createdOn: Date.now(), unknown: 123 });

assert.isDefined(entityData.unknown);
});
});

Expand Down

0 comments on commit 4ba1ce6

Please sign in to comment.