mirror of
https://github.com/vale981/grapher
synced 2025-03-05 17:41:41 -05:00
added intercompute deep for large-scale security concerns regarding exposure
This commit is contained in:
parent
9cc17ff602
commit
06c28112c5
3 changed files with 102 additions and 7 deletions
|
@ -6,6 +6,7 @@ import enforceMaxDepth from './lib/enforceMaxDepth.js';
|
|||
import enforceMaxLimit from './lib/enforceMaxLimit.js';
|
||||
import intersectDeep from './lib/intersectDeep.js';
|
||||
import computeDeepFunctions from './lib/computeDeepFunctions.js';
|
||||
import intercomputeDeep from './lib/intercomputeDeep.js';
|
||||
import deepClone from '../query/lib/deepClone';
|
||||
import restrictFieldsFn from './lib/restrictFields.js';
|
||||
import restrictLinks from './lib/restrictLinks.js';
|
||||
|
@ -83,7 +84,7 @@ export default class Exposure {
|
|||
return body;
|
||||
}
|
||||
|
||||
return intersectDeep(this.getBody(userId), body);
|
||||
return intercomputeDeep(this.getBody(userId), body);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,12 +96,12 @@ export default class Exposure {
|
|||
}
|
||||
|
||||
if (_.isFunction(this.config.body)) {
|
||||
return computeDeepFunctions(
|
||||
return deepClone(
|
||||
this.config.body.call(this, userId),
|
||||
userId
|
||||
);
|
||||
} else {
|
||||
return computeDeepFunctions(this.config.body, userId);
|
||||
return deepClone(this.config.body, userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
48
lib/exposure/lib/intercomputeDeep.js
Normal file
48
lib/exposure/lib/intercomputeDeep.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
import deepClone from '../../query/lib/deepClone';
|
||||
|
||||
/**
|
||||
* Deep Inter Computation
|
||||
*/
|
||||
export default function intercomputeDeep(main, second, ...args) {
|
||||
let object = {};
|
||||
|
||||
_.each(main, (value, key) => {
|
||||
if (second[key] !== undefined) {
|
||||
// if the main value is a function, we run it.
|
||||
if (_.isFunction(value)) {
|
||||
value = value.call(null, ...args);
|
||||
}
|
||||
|
||||
// if the main value is undefined or false, we skip the merge
|
||||
if (value === undefined || value === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the main value is an object
|
||||
if (_.isObject(value)) {
|
||||
if (_.isObject(second[key])) {
|
||||
// if the second one is an object as well we run recursively run the intersection
|
||||
object[key] = intercomputeDeep(value, second[key], ...args);
|
||||
}
|
||||
// if it is not, then we will ignore it, because it won't make sense.
|
||||
// to merge {a: 1} with 1.
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if the main value is not an object, a truthy value like 1
|
||||
if (_.isObject(second[key])) {
|
||||
// if the second value is an object, then we will keep it.
|
||||
// this won't cause problem with deep nesting because
|
||||
// when you specify links you will have the main value as an object
|
||||
|
||||
object[key] = deepClone(second[key]);
|
||||
} else {
|
||||
// if the second value is not an object, we just store the first value
|
||||
object[key] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return object;
|
||||
}
|
|
@ -2,6 +2,7 @@ import restrictFields from '../../lib/restrictFields.js';
|
|||
import enforceMaxLimit from '../../lib/enforceMaxLimit.js';
|
||||
import intersectDeep from '../../lib/intersectDeep.js';
|
||||
import computeDeepFunctions from '../../lib/computeDeepFunctions.js';
|
||||
import intercomputeDeep from '../../lib/intercomputeDeep.js';
|
||||
import enforceMaxDepth, {getDepth} from '../../lib/enforceMaxDepth.js';
|
||||
import CollectionNode from '../../../query/nodes/collectionNode.js';
|
||||
|
||||
|
@ -200,7 +201,7 @@ describe('Unit Tests', function () {
|
|||
Object.freeze(obj1);
|
||||
Object.freeze(obj2);
|
||||
|
||||
const result = intersectDeep(obj1, obj2);
|
||||
const result = intercomputeDeep(obj1, obj2);
|
||||
|
||||
assert.isObject(result);
|
||||
assert.equal(result.a, 1);
|
||||
|
@ -214,9 +215,7 @@ describe('Unit Tests', function () {
|
|||
assert.isUndefined(result.d.d1.d12);
|
||||
assert.isUndefined(result.d.d2);
|
||||
assert.isUndefined(result.testUndefined);
|
||||
|
||||
assert.isObject(result.d.d1.d13);
|
||||
assert.equal(result.d.d1.d13.d131, 1);
|
||||
assert.isUndefined(result.d.d1.d13);
|
||||
});
|
||||
|
||||
it('Should compute functions nested', function () {
|
||||
|
@ -237,5 +236,52 @@ describe('Unit Tests', function () {
|
|||
assert.equal(newObject.value.item, 'test');
|
||||
assert.isObject(newObject.b.value);
|
||||
assert.equal(newObject.b.value.item, 'test');
|
||||
});
|
||||
|
||||
it('Should work intersect with computation and with infinite recursion avoidance', function () {
|
||||
const link2 = (item) => {
|
||||
return {
|
||||
item,
|
||||
link1
|
||||
}
|
||||
};
|
||||
|
||||
const link1 = (item) => {
|
||||
return {
|
||||
item,
|
||||
link2
|
||||
}
|
||||
};
|
||||
|
||||
const obj1 = {
|
||||
a: 1,
|
||||
link1
|
||||
};
|
||||
|
||||
const obj2 = {
|
||||
a: {
|
||||
a1: 1
|
||||
},
|
||||
link1: {
|
||||
item: 1,
|
||||
link2: {
|
||||
item: 1,
|
||||
link1: {
|
||||
item: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = intercomputeDeep(obj1, obj2, 'test');
|
||||
|
||||
assert.isObject(result.a);
|
||||
assert.isDefined(result.a.a1);
|
||||
assert.isObject(result.link1);
|
||||
assert.equal(result.link1.item, 'test');
|
||||
assert.isObject(result.link1.link2);
|
||||
assert.equal(result.link1.link2.item, 'test');
|
||||
assert.isObject(result.link1.link2.link1);
|
||||
assert.equal(result.link1.link2.link1.item, 'test');
|
||||
})
|
||||
});
|
Loading…
Add table
Reference in a new issue