[SIEM] Fixes REST formatter bugs from io-ts migration

## Summary

Fixes io-ts formatter bugs for REST and validation by:

* First trying to get the correct key from the io-ts context. If no keys are found, then it will fall back on trying to get the first name from the context.
* If the key is a value and an object then this will do a `JSON.stringify()` on the value object
* This fixes a few places where `formatError` was not being used within the code base resulting in `[object Object]` within the validations to show up.

### Checklist

- [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
This commit is contained in:
Frank Hassanabad 2020-06-18 08:16:39 -06:00 committed by GitHub
parent 9e8448fc06
commit e552a96121
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 343 additions and 201 deletions

View file

@ -27,8 +27,8 @@ export const DefaultCommentsArray: DefaultCommentsArrayC = new t.Type<
>(
'DefaultCommentsArray',
t.array(comment).is,
(input): Either<t.Errors, CommentsArray> =>
input == null ? t.success([]) : t.array(comment).decode(input),
(input, context): Either<t.Errors, CommentsArray> =>
input == null ? t.success([]) : t.array(comment).validate(input, context),
t.identity
);
@ -43,7 +43,7 @@ export const DefaultCommentsPartialArray: DefaultCommentsPartialArrayC = new t.T
>(
'DefaultCommentsPartialArray',
t.array(commentPartial).is,
(input): Either<t.Errors, CommentsPartialArray> =>
input == null ? t.success([]) : t.array(commentPartial).decode(input),
(input, context): Either<t.Errors, CommentsPartialArray> =>
input == null ? t.success([]) : t.array(commentPartial).validate(input, context),
t.identity
);

View file

@ -22,7 +22,7 @@ export const DefaultEntryArray: DefaultEntriesArrayC = new t.Type<
>(
'DefaultEntryArray',
t.array(entries).is,
(input): Either<t.Errors, EntriesArray> =>
input == null ? t.success([]) : t.array(entries).decode(input),
(input, context): Either<t.Errors, EntriesArray> =>
input == null ? t.success([]) : t.array(entries).validate(input, context),
t.identity
);

View file

@ -24,7 +24,7 @@ export const DefaultNamespace: DefaultNamespaceC = new t.Type<
>(
'DefaultNamespace',
namespaceType.is,
(input): Either<t.Errors, NamespaceType> =>
input == null ? t.success('single') : namespaceType.decode(input),
(input, context): Either<t.Errors, NamespaceType> =>
input == null ? t.success('single') : namespaceType.validate(input, context),
t.identity
);

View file

@ -625,7 +625,7 @@ describe('add prepackaged rules schema', () => {
const decoded = addPrepackagedRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']);
expect(message.schema).toEqual({});
});
@ -776,7 +776,9 @@ describe('add prepackaged rules schema', () => {
const decoded = addPrepackagedRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "max_signals"',
]);
expect(message.schema).toEqual({});
});
@ -789,7 +791,7 @@ describe('add prepackaged rules schema', () => {
const decoded = addPrepackagedRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']);
expect(message.schema).toEqual({});
});
@ -837,9 +839,9 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to ""',
'Invalid value "1" supplied to ""',
'Invalid value "2" supplied to ""',
'Invalid value "0" supplied to "tags"',
'Invalid value "1" supplied to "tags"',
'Invalid value "2" supplied to "tags"',
]);
expect(message.schema).toEqual({});
});
@ -871,7 +873,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "framework"',
'Invalid value "undefined" supplied to "threat,framework"',
]);
expect(message.schema).toEqual({});
});
@ -899,7 +901,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "tactic"',
'Invalid value "undefined" supplied to "threat,tactic"',
]);
expect(message.schema).toEqual({});
});
@ -925,7 +927,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "technique"',
'Invalid value "undefined" supplied to "threat,technique"',
]);
expect(message.schema).toEqual({});
});
@ -959,8 +961,8 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to ""',
'Invalid value "4" supplied to ""',
'Invalid value "5" supplied to "false_positives"',
'Invalid value "4" supplied to "false_positives"',
]);
expect(message.schema).toEqual({});
});
@ -1184,7 +1186,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "group"',
'Invalid value "undefined" supplied to "actions,group"',
]);
expect(message.schema).toEqual({});
});
@ -1198,7 +1200,9 @@ describe('add prepackaged rules schema', () => {
const decoded = addPrepackagedRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "actions,id"',
]);
expect(message.schema).toEqual({});
});
@ -1212,7 +1216,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1227,7 +1231,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "params"',
'Invalid value "undefined" supplied to "actions,params"',
]);
expect(message.schema).toEqual({});
});
@ -1249,7 +1253,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1323,8 +1327,7 @@ describe('add prepackaged rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
// TODO: Fix/Change the formatErrors to be better able to handle objects
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"somethingHere":"something else"}" supplied to "note"',
]);
expect(message.schema).toEqual({});
});

View file

@ -250,9 +250,8 @@ describe('create_rules_bulk_schema', () => {
const decoded = createRulesBulkSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const output = foldLeftRight(checked);
// TODO: We should change the formatter used to better print objects
expect(formatErrors(output.errors)).toEqual([
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"something":"some object"}" supplied to "note"',
]);
expect(output.schema).toEqual({});
});

View file

@ -614,7 +614,7 @@ describe('create rules schema', () => {
const decoded = createRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']);
expect(message.schema).toEqual({});
});
@ -721,7 +721,9 @@ describe('create rules schema', () => {
const decoded = createRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "max_signals"',
]);
expect(message.schema).toEqual({});
});
@ -734,7 +736,7 @@ describe('create rules schema', () => {
const decoded = createRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']);
expect(message.schema).toEqual({});
});
@ -782,9 +784,9 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to ""',
'Invalid value "1" supplied to ""',
'Invalid value "2" supplied to ""',
'Invalid value "0" supplied to "tags"',
'Invalid value "1" supplied to "tags"',
'Invalid value "2" supplied to "tags"',
]);
expect(message.schema).toEqual({});
});
@ -816,7 +818,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "framework"',
'Invalid value "undefined" supplied to "threat,framework"',
]);
expect(message.schema).toEqual({});
});
@ -844,7 +846,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "tactic"',
'Invalid value "undefined" supplied to "threat,tactic"',
]);
expect(message.schema).toEqual({});
});
@ -870,7 +872,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "technique"',
'Invalid value "undefined" supplied to "threat,technique"',
]);
expect(message.schema).toEqual({});
});
@ -902,8 +904,8 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to ""',
'Invalid value "4" supplied to ""',
'Invalid value "5" supplied to "false_positives"',
'Invalid value "4" supplied to "false_positives"',
]);
expect(message.schema).toEqual({});
});
@ -1081,7 +1083,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "group"',
'Invalid value "undefined" supplied to "actions,group"',
]);
expect(message.schema).toEqual({});
});
@ -1095,7 +1097,9 @@ describe('create rules schema', () => {
const decoded = createRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "actions,id"',
]);
expect(message.schema).toEqual({});
});
@ -1109,7 +1113,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1124,7 +1128,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "params"',
'Invalid value "undefined" supplied to "actions,params"',
]);
expect(message.schema).toEqual({});
});
@ -1146,7 +1150,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1198,8 +1202,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
// TODO: Fix/Change the formatErrors to be better able to handle objects
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"somethingHere":"something else"}" supplied to "note"',
]);
expect(message.schema).toEqual({});
});

View file

@ -34,10 +34,9 @@ describe('create rules schema', () => {
const decoded = exportRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
// TODO: Change formatter to display a better value than [object Object]
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "objects"',
'Invalid value "[object Object]" supplied to ""',
'Invalid value "{}" supplied to "({| objects: Array<{| rule_id: string |}> |} | null)"',
]);
expect(message.schema).toEqual(payload);
});
@ -70,10 +69,9 @@ describe('create rules schema', () => {
const decoded = exportRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
// TODO: Change formatter to display a better value than [object Object]
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "objects,rule_id"',
'Invalid value "[object Object]" supplied to ""',
'Invalid value "{"objects":[{"id":"4a7ff83d-3055-4bb2-ba68-587b9c6c15a4"}]}" supplied to "({| objects: Array<{| rule_id: string |}> |} | null)"',
]);
expect(message.schema).toEqual({});
});
@ -120,7 +118,9 @@ describe('create rules schema', () => {
const decoded = exportRulesQuerySchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "10" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "10" supplied to "file_name"',
]);
expect(message.schema).toEqual({});
});
@ -151,7 +151,7 @@ describe('create rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "invalid string" supplied to ""',
'Invalid value "invalid string" supplied to "exclude_export_details"',
]);
expect(message.schema).toEqual({});
});

View file

@ -625,7 +625,7 @@ describe('import rules schema', () => {
const decoded = importRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']);
expect(message.schema).toEqual({});
});
@ -773,7 +773,9 @@ describe('import rules schema', () => {
const decoded = importRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "max_signals"',
]);
expect(message.schema).toEqual({});
});
@ -786,7 +788,7 @@ describe('import rules schema', () => {
const decoded = importRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']);
expect(message.schema).toEqual({});
});
@ -834,9 +836,9 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to ""',
'Invalid value "1" supplied to ""',
'Invalid value "2" supplied to ""',
'Invalid value "0" supplied to "tags"',
'Invalid value "1" supplied to "tags"',
'Invalid value "2" supplied to "tags"',
]);
expect(message.schema).toEqual({});
});
@ -868,7 +870,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "framework"',
'Invalid value "undefined" supplied to "threat,framework"',
]);
expect(message.schema).toEqual({});
});
@ -896,7 +898,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "tactic"',
'Invalid value "undefined" supplied to "threat,tactic"',
]);
expect(message.schema).toEqual({});
});
@ -922,7 +924,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "technique"',
'Invalid value "undefined" supplied to "threat,technique"',
]);
expect(message.schema).toEqual({});
});
@ -954,8 +956,8 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to ""',
'Invalid value "4" supplied to ""',
'Invalid value "5" supplied to "false_positives"',
'Invalid value "4" supplied to "false_positives"',
]);
expect(message.schema).toEqual({});
});
@ -1254,7 +1256,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "invalid-string" supplied to ""',
'Invalid value "invalid-string" supplied to "overwrite"',
]);
expect(message.schema).toEqual({});
});
@ -1377,7 +1379,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "group"',
'Invalid value "undefined" supplied to "actions,group"',
]);
expect(message.schema).toEqual({});
});
@ -1391,7 +1393,9 @@ describe('import rules schema', () => {
const decoded = importRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "actions,id"',
]);
expect(message.schema).toEqual({});
});
@ -1405,7 +1409,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1420,7 +1424,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "params"',
'Invalid value "undefined" supplied to "actions,params"',
]);
expect(message.schema).toEqual({});
});
@ -1442,7 +1446,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1513,8 +1517,7 @@ describe('import rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
// TODO: Fix/Change the formatErrors to be better able to handle objects
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"somethingHere":"something else"}" supplied to "note"',
]);
expect(message.schema).toEqual({});
});

View file

@ -92,9 +92,8 @@ describe('patch_rules_bulk_schema', () => {
const decoded = patchRulesBulkSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const output = foldLeftRight(checked);
// TODO: Fix the formatter to give something better than [object Object]
expect(formatErrors(output.errors)).toEqual([
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"someprop":"some value here"}" supplied to "note"',
]);
expect(output.schema).toEqual({});
});

View file

@ -1065,9 +1065,8 @@ describe('patch_rules_schema', () => {
const decoded = patchRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
// TODO: Change the formatter to output something more readable than [object Object]
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"someProperty":"something else here"}" supplied to "note"',
]);
expect(message.schema).toEqual({});
});

View file

@ -246,9 +246,8 @@ describe('update_rules_bulk_schema', () => {
const decoded = updateRulesBulkSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const output = foldLeftRight(checked);
// TODO: We should change the formatter used to better print objects
expect(formatErrors(output.errors)).toEqual([
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"something":"some object"}" supplied to "note"',
]);
expect(output.schema).toEqual({});
});

View file

@ -608,7 +608,7 @@ describe('update rules schema', () => {
const decoded = updateRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']);
expect(message.schema).toEqual({});
});
@ -756,7 +756,9 @@ describe('update rules schema', () => {
const decoded = updateRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "max_signals"',
]);
expect(message.schema).toEqual({});
});
@ -769,7 +771,7 @@ describe('update rules schema', () => {
const decoded = updateRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']);
expect(message.schema).toEqual({});
});
@ -817,9 +819,9 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to ""',
'Invalid value "1" supplied to ""',
'Invalid value "2" supplied to ""',
'Invalid value "0" supplied to "tags"',
'Invalid value "1" supplied to "tags"',
'Invalid value "2" supplied to "tags"',
]);
expect(message.schema).toEqual({});
});
@ -851,7 +853,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "framework"',
'Invalid value "undefined" supplied to "threat,framework"',
]);
expect(message.schema).toEqual({});
});
@ -879,7 +881,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "tactic"',
'Invalid value "undefined" supplied to "threat,tactic"',
]);
expect(message.schema).toEqual({});
});
@ -905,7 +907,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "technique"',
'Invalid value "undefined" supplied to "threat,technique"',
]);
expect(message.schema).toEqual({});
});
@ -937,8 +939,8 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to ""',
'Invalid value "4" supplied to ""',
'Invalid value "5" supplied to "false_positives"',
'Invalid value "4" supplied to "false_positives"',
]);
expect(message.schema).toEqual({});
});
@ -1173,7 +1175,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "group"',
'Invalid value "undefined" supplied to "actions,group"',
]);
expect(message.schema).toEqual({});
});
@ -1187,7 +1189,9 @@ describe('update rules schema', () => {
const decoded = updateRulesSchema.decode(payload);
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "actions,id"',
]);
expect(message.schema).toEqual({});
});
@ -1201,7 +1205,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1216,7 +1220,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "params"',
'Invalid value "undefined" supplied to "actions,params"',
]);
expect(message.schema).toEqual({});
});
@ -1238,7 +1242,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "undefined" supplied to "action_type_id"',
'Invalid value "undefined" supplied to "actions,action_type_id"',
]);
expect(message.schema).toEqual({});
});
@ -1323,8 +1327,7 @@ describe('update rules schema', () => {
const checked = exactCheck(payload, decoded);
const message = pipe(checked, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
// TODO: Fix/Change the formatErrors to be better able to handle objects
'Invalid value "[object Object]" supplied to "note"',
'Invalid value "{"somethingHere":"something else"}" supplied to "note"',
]);
expect(message.schema).toEqual({});
});

View file

@ -33,7 +33,9 @@ describe('default_boolean_true', () => {
const decoded = DefaultBooleanTrue.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultBooleanTrue"',
]);
expect(message.schema).toEqual({});
});

View file

@ -24,7 +24,9 @@ describe('default_from_string', () => {
const decoded = DefaultFromString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultFromString"',
]);
expect(message.schema).toEqual({});
});

View file

@ -39,7 +39,9 @@ describe('default_actions_array', () => {
const decoded = DefaultActionsArray.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultActionsArray"',
]);
expect(message.schema).toEqual({});
});

View file

@ -15,7 +15,8 @@ import { actions, Actions } from '../common/schemas';
export const DefaultActionsArray = new t.Type<Actions, Actions, unknown>(
'DefaultActionsArray',
actions.is,
(input): Either<t.Errors, Actions> => (input == null ? t.success([]) : actions.decode(input)),
(input, context): Either<t.Errors, Actions> =>
input == null ? t.success([]) : actions.validate(input, context),
t.identity
);

View file

@ -33,7 +33,9 @@ describe('default_boolean_false', () => {
const decoded = DefaultBooleanFalse.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultBooleanFalse"',
]);
expect(message.schema).toEqual({});
});

View file

@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultBooleanFalse = new t.Type<boolean, boolean, unknown>(
'DefaultBooleanFalse',
t.boolean.is,
(input): Either<t.Errors, boolean> =>
input == null ? t.success(false) : t.boolean.decode(input),
(input, context): Either<t.Errors, boolean> =>
input == null ? t.success(false) : t.boolean.validate(input, context),
t.identity
);

View file

@ -14,7 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultBooleanTrue = new t.Type<boolean, boolean, unknown>(
'DefaultBooleanTrue',
t.boolean.is,
(input): Either<t.Errors, boolean> => (input == null ? t.success(true) : t.boolean.decode(input)),
(input, context): Either<t.Errors, boolean> =>
input == null ? t.success(true) : t.boolean.validate(input, context),
t.identity
);

View file

@ -24,7 +24,9 @@ describe('default_empty_string', () => {
const decoded = DefaultEmptyString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultEmptyString"',
]);
expect(message.schema).toEqual({});
});

View file

@ -14,7 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultEmptyString = new t.Type<string, string, unknown>(
'DefaultEmptyString',
t.string.is,
(input): Either<t.Errors, string> => (input == null ? t.success('') : t.string.decode(input)),
(input, context): Either<t.Errors, string> =>
input == null ? t.success('') : t.string.validate(input, context),
t.identity
);

View file

@ -24,7 +24,9 @@ describe('default_export_file_name', () => {
const decoded = DefaultExportFileName.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultExportFileName"',
]);
expect(message.schema).toEqual({});
});

View file

@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultExportFileName = new t.Type<string, string, unknown>(
'DefaultExportFileName',
t.string.is,
(input): Either<t.Errors, string> =>
input == null ? t.success('export.ndjson') : t.string.decode(input),
(input, context): Either<t.Errors, string> =>
input == null ? t.success('export.ndjson') : t.string.validate(input, context),
t.identity
);

View file

@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultFromString = new t.Type<string, string, unknown>(
'DefaultFromString',
t.string.is,
(input): Either<t.Errors, string> =>
input == null ? t.success('now-6m') : t.string.decode(input),
(input, context): Either<t.Errors, string> =>
input == null ? t.success('now-6m') : t.string.validate(input, context),
t.identity
);

View file

@ -24,7 +24,9 @@ describe('default_interval_string', () => {
const decoded = DefaultIntervalString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultIntervalString"',
]);
expect(message.schema).toEqual({});
});

View file

@ -14,7 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultIntervalString = new t.Type<string, string, unknown>(
'DefaultIntervalString',
t.string.is,
(input): Either<t.Errors, string> => (input == null ? t.success('5m') : t.string.decode(input)),
(input, context): Either<t.Errors, string> =>
input == null ? t.success('5m') : t.string.validate(input, context),
t.identity
);

View file

@ -25,7 +25,9 @@ describe('default_language_string', () => {
const decoded = DefaultLanguageString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultLanguageString"',
]);
expect(message.schema).toEqual({});
});

View file

@ -15,8 +15,8 @@ import { language } from '../common/schemas';
export const DefaultLanguageString = new t.Type<string, string, unknown>(
'DefaultLanguageString',
t.string.is,
(input): Either<t.Errors, string> =>
input == null ? t.success('kuery') : language.decode(input),
(input, context): Either<t.Errors, string> =>
input == null ? t.success('kuery') : language.validate(input, context),
t.identity
);

View file

@ -25,7 +25,9 @@ describe('default_from_string', () => {
const decoded = DefaultMaxSignalsNumber.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultMaxSignals"',
]);
expect(message.schema).toEqual({});
});
@ -34,7 +36,9 @@ describe('default_from_string', () => {
const decoded = DefaultMaxSignalsNumber.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to "DefaultMaxSignals"',
]);
expect(message.schema).toEqual({});
});
@ -43,7 +47,9 @@ describe('default_from_string', () => {
const decoded = DefaultMaxSignalsNumber.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "DefaultMaxSignals"',
]);
expect(message.schema).toEqual({});
});

View file

@ -23,8 +23,8 @@ export const DefaultMaxSignalsNumber: DefaultMaxSignalsNumberC = new t.Type<
>(
'DefaultMaxSignals',
t.number.is,
(input): Either<t.Errors, number> => {
return input == null ? t.success(DEFAULT_MAX_SIGNALS) : max_signals.decode(input);
(input, context): Either<t.Errors, number> => {
return input == null ? t.success(DEFAULT_MAX_SIGNALS) : max_signals.validate(input, context);
},
t.identity
);

View file

@ -33,7 +33,9 @@ describe('default_page', () => {
const decoded = DefaultPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "NaN" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});
@ -42,7 +44,9 @@ describe('default_page', () => {
const decoded = DefaultPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "NaN" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});
@ -51,7 +55,9 @@ describe('default_page', () => {
const decoded = DefaultPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});
@ -60,7 +66,9 @@ describe('default_page', () => {
const decoded = DefaultPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});

View file

@ -17,13 +17,13 @@ import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_
export const DefaultPage = new t.Type<number, number, unknown>(
'DefaultPerPage',
t.number.is,
(input): Either<t.Errors, number> => {
(input, context): Either<t.Errors, number> => {
if (input == null) {
return t.success(1);
} else if (typeof input === 'string') {
return PositiveIntegerGreaterThanZero.decode(parseInt(input, 10));
return PositiveIntegerGreaterThanZero.validate(parseInt(input, 10), context);
} else {
return PositiveIntegerGreaterThanZero.decode(input);
return PositiveIntegerGreaterThanZero.validate(input, context);
}
},
t.identity

View file

@ -33,7 +33,9 @@ describe('default_per_page', () => {
const decoded = DefaultPerPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "NaN" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});
@ -42,7 +44,9 @@ describe('default_per_page', () => {
const decoded = DefaultPerPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "NaN" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});
@ -51,7 +55,9 @@ describe('default_per_page', () => {
const decoded = DefaultPerPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});
@ -60,7 +66,9 @@ describe('default_per_page', () => {
const decoded = DefaultPerPage.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "DefaultPerPage"',
]);
expect(message.schema).toEqual({});
});

View file

@ -17,13 +17,13 @@ import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_
export const DefaultPerPage = new t.Type<number, number, unknown>(
'DefaultPerPage',
t.number.is,
(input): Either<t.Errors, number> => {
(input, context): Either<t.Errors, number> => {
if (input == null) {
return t.success(20);
} else if (typeof input === 'string') {
return PositiveIntegerGreaterThanZero.decode(parseInt(input, 10));
return PositiveIntegerGreaterThanZero.validate(parseInt(input, 10), context);
} else {
return PositiveIntegerGreaterThanZero.decode(input);
return PositiveIntegerGreaterThanZero.validate(input, context);
}
},
t.identity

View file

@ -33,7 +33,9 @@ describe('default_string_array', () => {
const decoded = DefaultStringArray.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultStringArray"',
]);
expect(message.schema).toEqual({});
});

View file

@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultStringArray = new t.Type<string[], string[], unknown>(
'DefaultStringArray',
t.array(t.string).is,
(input): Either<t.Errors, string[]> =>
input == null ? t.success([]) : t.array(t.string).decode(input),
(input, context): Either<t.Errors, string[]> =>
input == null ? t.success([]) : t.array(t.string).validate(input, context),
t.identity
);

View file

@ -33,7 +33,9 @@ describe('default_string_boolean_false', () => {
const decoded = DefaultStringBooleanFalse.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultStringBooleanFalse"',
]);
expect(message.schema).toEqual({});
});
@ -78,7 +80,9 @@ describe('default_string_boolean_false', () => {
const decoded = DefaultStringBooleanFalse.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "junk" supplied to "DefaultStringBooleanFalse"',
]);
expect(message.schema).toEqual({});
});
@ -87,7 +91,9 @@ describe('default_string_boolean_false', () => {
const decoded = DefaultStringBooleanFalse.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "" supplied to "DefaultStringBooleanFalse"',
]);
expect(message.schema).toEqual({});
});
});

View file

@ -15,7 +15,7 @@ import { Either } from 'fp-ts/lib/Either';
export const DefaultStringBooleanFalse = new t.Type<boolean, boolean, unknown>(
'DefaultStringBooleanFalse',
t.boolean.is,
(input): Either<t.Errors, boolean> => {
(input, context): Either<t.Errors, boolean> => {
if (input == null) {
return t.success(false);
} else if (typeof input === 'string' && input.toLowerCase() === 'true') {
@ -23,7 +23,7 @@ export const DefaultStringBooleanFalse = new t.Type<boolean, boolean, unknown>(
} else if (typeof input === 'string' && input.toLowerCase() === 'false') {
return t.success(false);
} else {
return t.boolean.decode(input);
return t.boolean.validate(input, context);
}
},
t.identity

View file

@ -47,7 +47,9 @@ describe('default_threat_null', () => {
const decoded = DefaultThreatArray.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultThreatArray"',
]);
expect(message.schema).toEqual({});
});

View file

@ -15,7 +15,8 @@ import { Threat, threat } from '../common/schemas';
export const DefaultThreatArray = new t.Type<Threat, Threat, unknown>(
'DefaultThreatArray',
threat.is,
(input): Either<t.Errors, Threat> => (input == null ? t.success([]) : threat.decode(input)),
(input, context): Either<t.Errors, Threat> =>
input == null ? t.success([]) : threat.validate(input, context),
t.identity
);

View file

@ -25,7 +25,9 @@ describe('default_throttle_null', () => {
const decoded = DefaultThrottleNull.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultThreatNull"',
]);
expect(message.schema).toEqual({});
});

View file

@ -15,8 +15,8 @@ import { ThrottleOrNull, throttle } from '../common/schemas';
export const DefaultThrottleNull = new t.Type<ThrottleOrNull, ThrottleOrNull, unknown>(
'DefaultThreatNull',
throttle.is,
(input): Either<t.Errors, ThrottleOrNull> =>
input == null ? t.success(null) : throttle.decode(input),
(input, context): Either<t.Errors, ThrottleOrNull> =>
input == null ? t.success(null) : throttle.validate(input, context),
t.identity
);

View file

@ -24,7 +24,9 @@ describe('default_to_string', () => {
const decoded = DefaultToString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultToString"',
]);
expect(message.schema).toEqual({});
});

View file

@ -12,9 +12,10 @@ import { Either } from 'fp-ts/lib/Either';
* - If null or undefined, then a default of the string "now" will be used
*/
export const DefaultToString = new t.Type<string, string, unknown>(
'DefaultFromString',
'DefaultToString',
t.string.is,
(input): Either<t.Errors, string> => (input == null ? t.success('now') : t.string.decode(input)),
(input, context): Either<t.Errors, string> =>
input == null ? t.success('now') : t.string.validate(input, context),
t.identity
);

View file

@ -24,7 +24,7 @@ describe('default_uuid', () => {
const decoded = DefaultUuid.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "DefaultUuid"']);
expect(message.schema).toEqual({});
});

View file

@ -18,8 +18,8 @@ import { NonEmptyString } from './non_empty_string';
export const DefaultUuid = new t.Type<string, string, unknown>(
'DefaultUuid',
t.string.is,
(input): Either<t.Errors, string> =>
input == null ? t.success(uuid.v4()) : NonEmptyString.decode(input),
(input, context): Either<t.Errors, string> =>
input == null ? t.success(uuid.v4()) : NonEmptyString.validate(input, context),
t.identity
);

View file

@ -24,7 +24,9 @@ describe('default_version_number', () => {
const decoded = DefaultVersionNumber.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to "DefaultVersionNumber"',
]);
expect(message.schema).toEqual({});
});
@ -33,7 +35,9 @@ describe('default_version_number', () => {
const decoded = DefaultVersionNumber.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "DefaultVersionNumber"',
]);
expect(message.schema).toEqual({});
});
@ -42,7 +46,9 @@ describe('default_version_number', () => {
const decoded = DefaultVersionNumber.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultVersionNumber"',
]);
expect(message.schema).toEqual({});
});

View file

@ -15,7 +15,8 @@ import { version, Version } from '../common/schemas';
export const DefaultVersionNumber = new t.Type<Version, Version, unknown>(
'DefaultVersionNumber',
version.is,
(input): Either<t.Errors, Version> => (input == null ? t.success(1) : version.decode(input)),
(input, context): Either<t.Errors, Version> =>
input == null ? t.success(1) : version.validate(input, context),
t.identity
);

View file

@ -25,7 +25,7 @@ describe('ios_date_string', () => {
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "1582677283067" supplied to ""',
'Invalid value "1582677283067" supplied to "IsoDateString"',
]);
expect(message.schema).toEqual({});
});
@ -35,7 +35,9 @@ describe('ios_date_string', () => {
const decoded = IsoDateString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "2000" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "2000" supplied to "IsoDateString"',
]);
expect(message.schema).toEqual({});
});
@ -45,7 +47,7 @@ describe('ios_date_string', () => {
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "Wed, 26 Feb 2020 00:36:20 GMT" supplied to ""',
'Invalid value "Wed, 26 Feb 2020 00:36:20 GMT" supplied to "IsoDateString"',
]);
expect(message.schema).toEqual({});
});

View file

@ -173,8 +173,8 @@ describe('lists_default_array', () => {
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to ""',
'Invalid value "5" supplied to ""',
'Invalid value "5" supplied to "listsWithDefaultArray"',
'Invalid value "5" supplied to "listsWithDefaultArray"',
]);
expect(message.schema).toEqual({});
});

View file

@ -24,8 +24,8 @@ export type ListOperator = t.TypeOf<typeof listOperator>;
export const ListsDefaultArray = new t.Type<List[], List[], unknown>(
'listsWithDefaultArray',
t.array(listAnd).is,
(input): Either<t.Errors, List[]> =>
input == null ? t.success([]) : t.array(listAnd).decode(input),
(input, context): Either<t.Errors, List[]> =>
input == null ? t.success([]) : t.array(listAnd).validate(input, context),
t.identity
);

View file

@ -24,7 +24,9 @@ describe('non_empty_string', () => {
const decoded = NonEmptyString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "NonEmptyString"',
]);
expect(message.schema).toEqual({});
});
@ -33,7 +35,9 @@ describe('non_empty_string', () => {
const decoded = NonEmptyString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "" supplied to "NonEmptyString"',
]);
expect(message.schema).toEqual({});
});
@ -42,7 +46,9 @@ describe('non_empty_string', () => {
const decoded = NonEmptyString.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value " " supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value " " supplied to "NonEmptyString"',
]);
expect(message.schema).toEqual({});
});
});

View file

@ -24,7 +24,9 @@ describe('only_false_allowed', () => {
const decoded = OnlyFalseAllowed.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "true" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "true" supplied to "DefaultBooleanTrue"',
]);
expect(message.schema).toEqual({});
});
@ -33,7 +35,9 @@ describe('only_false_allowed', () => {
const decoded = OnlyFalseAllowed.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultBooleanTrue"',
]);
expect(message.schema).toEqual({});
});

View file

@ -24,7 +24,9 @@ describe('positive_integer_greater_than_zero', () => {
const decoded = PositiveIntegerGreaterThanZero.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "0" supplied to "PositiveIntegerGreaterThanZero"',
]);
expect(message.schema).toEqual({});
});
@ -33,7 +35,9 @@ describe('positive_integer_greater_than_zero', () => {
const decoded = PositiveIntegerGreaterThanZero.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "PositiveIntegerGreaterThanZero"',
]);
expect(message.schema).toEqual({});
});
@ -42,7 +46,9 @@ describe('positive_integer_greater_than_zero', () => {
const decoded = PositiveIntegerGreaterThanZero.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "some string" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "some string" supplied to "PositiveIntegerGreaterThanZero"',
]);
expect(message.schema).toEqual({});
});
});

View file

@ -33,7 +33,9 @@ describe('positive_integer_greater_than_zero', () => {
const decoded = PositiveInteger.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "-1" supplied to "PositiveInteger"',
]);
expect(message.schema).toEqual({});
});
@ -42,7 +44,9 @@ describe('positive_integer_greater_than_zero', () => {
const decoded = PositiveInteger.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "some string" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "some string" supplied to "PositiveInteger"',
]);
expect(message.schema).toEqual({});
});
});

View file

@ -33,7 +33,9 @@ describe('default_string_array', () => {
const decoded = DefaultStringArray.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "5" supplied to "DefaultStringArray"',
]);
expect(message.schema).toEqual({});
});

View file

@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either';
export const ReferencesDefaultArray = new t.Type<string[], string[], unknown>(
'referencesWithDefaultArray',
t.array(t.string).is,
(input): Either<t.Errors, string[]> =>
input == null ? t.success([]) : t.array(t.string).decode(input),
(input, context): Either<t.Errors, string[]> =>
input == null ? t.success([]) : t.array(t.string).validate(input, context),
t.identity
);

View file

@ -33,7 +33,7 @@ describe('risk_score', () => {
const decoded = RiskScore.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "RiskScore"']);
expect(message.schema).toEqual({});
});
@ -42,7 +42,9 @@ describe('risk_score', () => {
const decoded = RiskScore.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "some string" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "some string" supplied to "RiskScore"',
]);
expect(message.schema).toEqual({});
});
@ -51,7 +53,7 @@ describe('risk_score', () => {
const decoded = RiskScore.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "101" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "101" supplied to "RiskScore"']);
expect(message.schema).toEqual({});
});
});

View file

@ -25,7 +25,7 @@ describe('uuid', () => {
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual([
'Invalid value "4656dc92-5832-11ea-8e2d" supplied to ""',
'Invalid value "4656dc92-5832-11ea-8e2d" supplied to "UUID"',
]);
expect(message.schema).toEqual({});
});
@ -35,7 +35,7 @@ describe('uuid', () => {
const decoded = UUID.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']);
expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "UUID"']);
expect(message.schema).toEqual({});
});
});

View file

@ -127,4 +127,45 @@ describe('utils', () => {
'Invalid value "Some existing error 1" supplied to "some string key 2"',
]);
});
test('will use a name context if it cannot find a keyContext', () => {
const context: t.Context = ([
{ key: '' },
{ key: '', type: { name: 'someName' } },
] as unknown) as t.Context;
const validationError1: t.ValidationError = {
value: 'Some existing error 1',
context,
};
const errors: t.Errors = [validationError1];
const output = formatErrors(errors);
expect(output).toEqual(['Invalid value "Some existing error 1" supplied to "someName"']);
});
test('will return an empty string if name does not exist but type does', () => {
const context: t.Context = ([{ key: '' }, { key: '', type: {} }] as unknown) as t.Context;
const validationError1: t.ValidationError = {
value: 'Some existing error 1',
context,
};
const errors: t.Errors = [validationError1];
const output = formatErrors(errors);
expect(output).toEqual(['Invalid value "Some existing error 1" supplied to ""']);
});
test('will stringify an error value', () => {
const context: t.Context = ([
{ key: '' },
{ key: 'some string key 2' },
] as unknown) as t.Context;
const validationError1: t.ValidationError = {
value: { foo: 'some error' },
context,
};
const errors: t.Errors = [validationError1];
const output = formatErrors(errors);
expect(output).toEqual([
'Invalid value "{"foo":"some error"}" supplied to "some string key 2"',
]);
});
});

View file

@ -5,19 +5,25 @@
*/
import * as t from 'io-ts';
import { isObject } from 'lodash/fp';
export const formatErrors = (errors: t.Errors): string[] => {
return errors.map((error) => {
if (error.message != null) {
return error.message;
} else {
const mappedContext = error.context
const keyContext = error.context
.filter(
(entry) => entry.key != null && !Number.isInteger(+entry.key) && entry.key.trim() !== ''
)
.map((entry) => entry.key)
.join(',');
return `Invalid value "${error.value}" supplied to "${mappedContext}"`;
const nameContext = error.context.find((entry) => entry.type?.name?.length > 0);
const suppliedValue =
keyContext !== '' ? keyContext : nameContext != null ? nameContext.type.name : '';
const value = isObject(error.value) ? JSON.stringify(error.value) : error.value;
return `Invalid value "${value}" supplied to "${suppliedValue}"`;
}
});
};

View file

@ -254,16 +254,14 @@ describe('import_rules_route', () => {
errors: [
{
error: {
// TODO: Change the formatter to do better than output [object Object]
message: '[object Object]',
message: 'Invalid value "undefined" supplied to "rule_id"',
status_code: 400,
},
rule_id: '(unknown id)',
},
{
error: {
// TODO: Change the formatter to do better than output [object Object]
message: '[object Object]',
message: 'Invalid value "undefined" supplied to "rule_id"',
status_code: 400,
},
rule_id: '(unknown id)',

View file

@ -365,9 +365,8 @@ describe('create_rules_stream_from_ndjson', () => {
references: [],
version: 1,
});
// TODO: Change the formatter to output something better than [object Object]
expect(resultOrError[1].message).toEqual(
'[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]'
'Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "name",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "rule_id"'
);
expect(resultOrError[2]).toEqual({
actions: [],

View file

@ -7,6 +7,7 @@ import { Transform } from 'stream';
import * as t from 'io-ts';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { formatErrors } from '../../../../common/format_errors';
import { importRuleValidateTypeDependents } from '../../../../common/detection_engine/schemas/request/import_rules_type_dependents';
import { exactCheck } from '../../../../common/exact_check';
import {
@ -32,7 +33,7 @@ export const validateRules = (): Transform => {
const decoded = importRulesSchema.decode(obj);
const checked = exactCheck(obj, decoded);
const onLeft = (errors: t.Errors): BadRequestError | ImportRulesSchemaDecoded => {
return new BadRequestError(errors.join());
return new BadRequestError(formatErrors(errors).join());
};
const onRight = (schema: ImportRulesSchema): BadRequestError | ImportRulesSchemaDecoded => {
const validationErrors = importRuleValidateTypeDependents(schema);

View file

@ -33,16 +33,14 @@ describe('get_existing_prepackaged_rules', () => {
});
test('should throw an exception if a pre-packaged rule is not valid', () => {
// TODO: Improve the error formatter around [object Object]
expect(() => getPrepackagedRules([{ not_valid_made_up_key: true }])).toThrow(
'name: "(rule name unknown)", rule_id: "(rule rule_id unknown)" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object], Full rule contents are:\n{\n "not_valid_made_up_key": true\n}'
'name: "(rule name unknown)", rule_id: "(rule rule_id unknown)" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "name",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "rule_id",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "not_valid_made_up_key": true\n}'
);
});
test('should throw an exception with a message having rule_id and name in it', () => {
// TODO: Improve the error formatter around [object Object]
expect(() => getPrepackagedRules([{ name: 'rule name', rule_id: 'id-123' }])).toThrow(
'name: "rule name", rule_id: "id-123" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: [object Object],[object Object],[object Object],[object Object],[object Object], Full rule contents are:\n{\n "name": "rule name",\n "rule_id": "id-123"\n}'
'name: "rule name", rule_id: "id-123" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "name": "rule name",\n "rule_id": "id-123"\n}'
);
});
});

View file

@ -7,6 +7,7 @@
import * as t from 'io-ts';
import { fold } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { formatErrors } from '../../../../common/format_errors';
import { exactCheck } from '../../../../common/exact_check';
import {
addPrepackagedRulesSchema,
@ -35,11 +36,9 @@ export const validateAllPrepackagedRules = (
`name: "${ruleName}", rule_id: "${ruleId}" within the folder rules/prepackaged_rules ` +
`is not a valid detection engine rule. Expect the system ` +
`to not work with pre-packaged rules until this rule is fixed ` +
`or the file is removed. Error is: ${errors.join()}, Full rule contents are:\n${JSON.stringify(
rule,
null,
2
)}`
`or the file is removed. Error is: ${formatErrors(
errors
).join()}, Full rule contents are:\n${JSON.stringify(rule, null, 2)}`
);
};

View file

@ -8,6 +8,7 @@ import { has, isString } from 'lodash/fp';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import * as t from 'io-ts';
import { formatErrors } from '../../../common/format_errors';
import { importRuleValidateTypeDependents } from '../../../common/detection_engine/schemas/request/import_rules_type_dependents';
import {
ImportRulesSchemaDecoded,
@ -47,7 +48,7 @@ export const validateRules = (): Transform => {
const decoded = importRulesSchema.decode(obj);
const checked = exactCheck(obj, decoded);
const onLeft = (errors: t.Errors): BadRequestError | ImportRulesSchemaDecoded => {
return new BadRequestError(errors.join());
return new BadRequestError(formatErrors(errors).join());
};
const onRight = (schema: ImportRulesSchema): BadRequestError | ImportRulesSchemaDecoded => {
const validationErrors = importRuleValidateTypeDependents(schema);