UNPKG

kindergarten

Version:

Kindergarten is a JavaScript library which helps programmers to achieve modular security using sandbox pattern

107 lines (84 loc) 3.06 kB
'use strict'; exports.__esModule = true; var _isString = require('lodash/isString'); var _isString2 = _interopRequireDefault(_isString); var _isFunction = require('lodash/isFunction'); var _isFunction2 = _interopRequireDefault(_isFunction); var _isUndefined = require('lodash/isUndefined'); var _isUndefined2 = _interopRequireDefault(_isUndefined); var _utils = require('../utils'); var _errors = require('../errors'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The definition of `guard` decorator. Guard decorator is used to protect * methods in the sandbox. You can pass the name of the rule as a first * argument otherwise the name of the rule will be detected from name of the * protected method. Second argument can be a callback function or return value * that should be returned when child is not allowed to perform certain action. * * Example: * * class Foo { * @guard * foo() {} * * @guard('watch') * bar() {} * * @guard('bar', '<div>Not allowed</div>') * baz() {} * } */ var guard = function guard() { /** * Name of the action that should be guarded. */ var action = arguments.length <= 0 ? undefined : arguments[0]; /** * True if the @guard decorator is called `@guard()` */ var isCalled = (0, _isString2.default)(action) || arguments.length === 0; /** * Return callback or value that should be returned in case guard method * throws `AccessDenied` error */ var callback = void 0; if (isCalled) { callback = arguments.length <= 1 ? undefined : arguments[1]; } var guardFunc = function guardFunc(target, name, descriptor) { var protectedMethod = descriptor.value; descriptor.value = function () { var _this = this; for (var _len = arguments.length, protectedMethodArgs = Array(_len), _key = 0; _key < _len; _key++) { protectedMethodArgs[_key] = arguments[_key]; } if (!(0, _utils.isPerimeter)(this) && !(0, _utils.isSandbox)(this) && !(0, _isFunction2.default)(this.guard)) { throw new Error('Guard decorator can only be used within perimeter or sandbox.'); } var guardCall = function guardCall() { return _this.guard.apply(_this, [isCalled && action ? action : name].concat(protectedMethodArgs)); }; /** * If callback is specified and guard method throws an error. Then we * need to return the result of the callback method; */ if (!(0, _isUndefined2.default)(callback)) { try { guardCall(); } catch (e) { if (e instanceof _errors.AccessDenied) { return (0, _isFunction2.default)(callback) ? callback.apply(this, protectedMethodArgs) : callback; } } } /** * Call the guard method of the governess */ guardCall(); return protectedMethod.apply(this, protectedMethodArgs); }; }; return isCalled ? guardFunc : guardFunc.apply(undefined, arguments); }; exports.default = guard;