2016-09-14 16:04:08 +03:00
|
|
|
import createGraph from '../query/lib/createGraph.js';
|
|
|
|
import recursiveCompose from '../query/lib/recursiveCompose.js';
|
2016-09-24 08:05:26 +03:00
|
|
|
import hypernova from '../query/hypernova/hypernova.js';
|
|
|
|
import ExposureConfigSchema from './exposure.config.schema.js';
|
|
|
|
import enforceMaxDepth from './lib/enforceMaxDepth.js';
|
|
|
|
import enforceMaxLimit from './lib/enforceMaxLimit.js';
|
|
|
|
import restrictFieldsFn from './lib/restrictFields.js';
|
|
|
|
|
|
|
|
let globalConfig = {};
|
2016-09-14 16:04:08 +03:00
|
|
|
|
|
|
|
export default class Exposure {
|
2016-09-24 08:05:26 +03:00
|
|
|
static setConfig(config) {
|
|
|
|
ExposureConfigSchema.validate(config);
|
|
|
|
ExposureConfigSchema.clean(config);
|
|
|
|
|
|
|
|
_.extend(globalConfig, config);
|
|
|
|
}
|
|
|
|
|
|
|
|
static getConfig() {
|
|
|
|
return globalConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
static restrictFields(...args) {
|
|
|
|
return restrictFieldsFn(...args);
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(collection, config = {}) {
|
|
|
|
collection.__isExposedForGrapher = true;
|
|
|
|
|
2016-09-14 16:04:08 +03:00
|
|
|
this.collection = collection;
|
|
|
|
this.name = `exposure_${collection._name}`;
|
|
|
|
|
2016-09-24 08:05:26 +03:00
|
|
|
this.config = config;
|
|
|
|
this._validateAndClean();
|
|
|
|
|
2016-09-14 16:04:08 +03:00
|
|
|
this.initSecurity();
|
|
|
|
this.initMethod();
|
|
|
|
this.initPublication();
|
|
|
|
}
|
|
|
|
|
2016-09-24 08:05:26 +03:00
|
|
|
_validateAndClean() {
|
|
|
|
if (typeof(this.config) === 'function') {
|
|
|
|
const firewall = this.config;
|
|
|
|
this.config = {firewall};
|
|
|
|
}
|
|
|
|
|
|
|
|
ExposureConfigSchema.validate(this.config);
|
|
|
|
ExposureConfigSchema.clean(this.config);
|
|
|
|
|
|
|
|
this.config = _.extend({}, Exposure.getConfig(), this.config);
|
|
|
|
}
|
|
|
|
|
2016-09-14 16:04:08 +03:00
|
|
|
initPublication() {
|
|
|
|
const collection = this.collection;
|
2016-09-24 08:05:26 +03:00
|
|
|
const config = this.config;
|
2016-09-14 16:04:08 +03:00
|
|
|
|
|
|
|
Meteor.publishComposite(this.name, function (body) {
|
|
|
|
return recursiveCompose(
|
2016-09-24 08:05:26 +03:00
|
|
|
enforceMaxDepth(
|
|
|
|
createGraph(collection, body),
|
|
|
|
config.maxDepth
|
|
|
|
),
|
2016-09-14 16:04:08 +03:00
|
|
|
this.userId
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
initMethod() {
|
|
|
|
const collection = this.collection;
|
2016-09-24 08:05:26 +03:00
|
|
|
const config = this.config;
|
2016-09-14 16:04:08 +03:00
|
|
|
|
|
|
|
Meteor.methods({
|
|
|
|
[this.name](body) {
|
2016-09-24 08:05:26 +03:00
|
|
|
return hypernova(
|
|
|
|
enforceMaxDepth(
|
|
|
|
createGraph(collection, body),
|
|
|
|
config.maxDepth
|
|
|
|
),
|
2016-09-14 16:04:08 +03:00
|
|
|
this.userId
|
|
|
|
);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
initSecurity() {
|
|
|
|
const collection = this.collection;
|
2016-09-24 08:05:26 +03:00
|
|
|
const {firewall, maxLimit, restrictedFields} = this.config;
|
|
|
|
const find = collection.find;
|
|
|
|
const findOne = collection.findOne;
|
2016-09-22 17:06:05 +03:00
|
|
|
|
2016-09-24 08:05:26 +03:00
|
|
|
collection.firewall = (filters, options, userId) => {
|
|
|
|
if (userId !== undefined) {
|
|
|
|
if (firewall) {
|
|
|
|
firewall.call({collection: collection}, filters, options, userId);
|
2016-09-14 16:04:08 +03:00
|
|
|
}
|
2016-09-22 13:46:27 +03:00
|
|
|
|
2016-09-24 08:05:26 +03:00
|
|
|
enforceMaxLimit(options, maxLimit);
|
2016-09-14 16:04:08 +03:00
|
|
|
|
2016-09-24 08:05:26 +03:00
|
|
|
if (restrictedFields) {
|
|
|
|
Exposure.restrictFields(filters, options, restrictedFields);
|
|
|
|
}
|
2016-09-14 16:04:08 +03:00
|
|
|
}
|
2016-09-24 08:05:26 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
collection.find = (filters, options, userId) => {
|
|
|
|
collection.firewall(filters, options, userId);
|
|
|
|
|
|
|
|
return find.call(collection, filters, options);
|
|
|
|
};
|
|
|
|
|
|
|
|
collection.findOne = (filters, options, userId) => {
|
|
|
|
collection.firewall(filters, options, userId);
|
|
|
|
|
|
|
|
return findOne.call(collection, filters, options);
|
2016-09-14 16:04:08 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|