const _ = require('lodash'), api = require('../../api'), helpers = require('../../helpers/register'), filters = require('../../filters'), common = require('../../lib/common'), routingService = require('../routing'); let generateProxyFunctions; generateProxyFunctions = function (name, permissions, isInternal) { const appRouter = routingService.registry.getRouter('appRouter'); var getPermission = function (perm) { return permissions[perm]; }, getPermissionToMethod = function (perm, method) { var perms = getPermission(perm); if (!perms) { return false; } return _.find(perms, function (name) { return name === method; }); }, runIfPermissionToMethod = function (perm, method, wrappedFunc, context, args) { // internal apps get all permissions if (isInternal) { return wrappedFunc.apply(context, args); } var permValue = getPermissionToMethod(perm, method); if (!permValue) { throw new Error(common.i18n.t('errors.apps.accessResourceWithoutPermission.error', { name: name, perm: perm, method: method })); } return wrappedFunc.apply(context, args); }, checkRegisterPermissions = function (perm, registerMethod) { return _.wrap(registerMethod, function (origRegister, name) { return runIfPermissionToMethod(perm, name, origRegister, this, _.toArray(arguments).slice(1)); }); }, passThruAppContextToApi = function (perm, apiMethods) { var appContext = { app: name }; return _.reduce(apiMethods, function (memo, apiMethod, methodName) { memo[methodName] = function () { var args = _.toArray(arguments), options = args[args.length - 1]; if (_.isObject(options)) { options.context = _.clone(appContext); } return apiMethod.apply({}, args); }; return memo; }, {}); }, proxy; proxy = { filters: { register: checkRegisterPermissions('filters', filters.registerFilter.bind(filters)), deregister: checkRegisterPermissions('filters', filters.deregisterFilter.bind(filters)) }, helpers: { register: checkRegisterPermissions('helpers', helpers.registerThemeHelper.bind(helpers)), registerAsync: checkRegisterPermissions('helpers', helpers.registerAsyncThemeHelper.bind(helpers)) }, // Expose the route service... routeService: { // This allows for mounting an entirely new Router at a path... registerRouter: checkRegisterPermissions('routes', appRouter.mountRouter.bind(appRouter)) }, // Mini proxy to the API - needs review api: { posts: passThruAppContextToApi('posts', _.pick(api.posts, 'browse', 'read', 'edit', 'add', 'destroy') ), tags: passThruAppContextToApi('tags', _.pick(api.tags, 'browse') ), notifications: passThruAppContextToApi('notifications', _.pick(api.notifications, 'browse', 'add', 'destroy') ), settings: passThruAppContextToApi('settings', _.pick(api.settings, 'browse', 'read', 'edit') ) } }; return proxy; }; function AppProxy(options) { if (!options.name) { throw new Error(common.i18n.t('errors.apps.mustProvideAppName.error')); } if (!options.permissions) { throw new Error(common.i18n.t('errors.apps.mustProvideAppPermissions.error')); } _.extend(this, generateProxyFunctions(options.name, options.permissions, options.internal)); } module.exports = AppProxy;