shyft
Version:
Model driven GraphQL API framework
970 lines (969 loc) • 49.8 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.processActionPermissions = exports.processViewEntityPermissions = exports.processEntityPermissions = exports.findEmptyEntityPermissions = exports.hasEmptyPermissions = exports.checkPermissionAdvanced = exports.buildActionPermissionFilter = exports.buildPermissionFilter = exports.buildPermissionFilterSingle = exports.buildLookupsPermissionFilter = exports.buildValuesPermissionFilter = exports.buildStatesPermissionFilter = exports.buildUserAttributesPermissionFilter = exports.isPermissionSimple = exports.checkPermissionSimple = exports.generatePermissionDescription = exports.validateActionLookupPermission = exports.findMissingPermissionStates = exports.findMissingPermissionAttributes = exports.findInvalidPermissionAttributes = exports.isPermissionsArray = exports.isPermission = exports.Permission = void 0;
var _ = __importStar(require("lodash"));
var util_1 = require("../util");
var Entity_1 = require("../entity/Entity");
var DataTypeUser_1 = require("../datatype/DataTypeUser");
var Mutation_1 = require("../mutation/Mutation");
var Subscription_1 = require("../subscription/Subscription");
var DataTypeState_1 = require("../datatype/DataTypeState");
/*
all permission rules are ...
- combined with OR on the same type level
- combined with AND among all types
- combined with OR among Permission objects
*/
var compatibilityList = [
['everyone', 'lookup', 'value', 'state'],
['authenticated', 'role', 'userAttribute', 'lookup', 'value', 'state'],
['role', 'userAttribute', 'lookup', 'value', 'state'],
];
var Permission = /** @class */ (function () {
/* eslint-enable no-undef */
function Permission() {
this.isEmpty = true;
this.everyoneCanAccess = false;
this.authenticatedCanAccess = false;
this.types = {};
this.roles = [];
this.userAttributes = [];
this.lookups = [];
this.values = [];
this.states = [];
return this;
}
Permission.prototype._checkCompatibility = function (type) {
var _this = this;
this.types[type] = true;
var found = compatibilityList.find(function (list) {
var allFound = true;
Object.keys(_this.types).map(function (key) {
if (!list.includes(key)) {
allFound = false;
}
});
return allFound;
});
util_1.passOrThrow(found, function () { return "Permission type '" + type + "' is incompatible with other types"; });
};
Permission.prototype.everyone = function () {
this.isEmpty = false;
this._checkCompatibility('everyone');
this.everyoneCanAccess = true;
return this;
};
Permission.prototype.authenticated = function () {
this.isEmpty = false;
this._checkCompatibility('authenticated');
this.authenticatedCanAccess = true;
return this;
};
Permission.prototype.role = function (name) {
this.isEmpty = false;
this._checkCompatibility('role');
util_1.passOrThrow(name, function () { return "Permission type 'role' expects a role name"; });
this.roles.push(name);
util_1.passOrThrow(this.roles.length === _.uniq(this.roles).length, function () { return "Duplicate role '" + name + "' for permission type 'role'"; });
return this;
};
Permission.prototype.userAttribute = function (attributeName) {
this.isEmpty = false;
this._checkCompatibility('userAttribute');
util_1.passOrThrow(attributeName, function () { return "Permission type 'userAttribute' expects an attribute name"; });
this.userAttributes.push(attributeName);
util_1.passOrThrow(this.userAttributes.length === _.uniq(this.userAttributes).length, function () {
return "Duplicate attribute name '" + attributeName + "' for permission type 'userAttribute'";
});
return this;
};
Permission.prototype.lookup = function (entity, lookupMap) {
this.isEmpty = false;
this._checkCompatibility('lookup');
util_1.passOrThrow(util_1.isFunction(entity) || Entity_1.isEntity(entity), function () { return "Permission type 'lookup' expects an entity"; });
util_1.passOrThrow(util_1.isMap(lookupMap, true), function () { return "Permission type 'lookup' expects a lookupMap"; });
this.lookups.push({
entity: entity,
lookupMap: lookupMap,
});
return this;
};
Permission.prototype.value = function (attributeName, value) {
this.isEmpty = false;
this._checkCompatibility('value');
util_1.passOrThrow(attributeName, function () { return "Permission type 'value' expects an attribute name"; });
util_1.passOrThrow(typeof value !== 'undefined', function () { return "Permission type 'value' expects a value"; });
this.values.push({
attributeName: attributeName,
value: value,
});
return this;
};
Permission.prototype.state = function (stateName) {
this.isEmpty = false;
this._checkCompatibility('state');
util_1.passOrThrow(stateName, function () { return "Permission type 'state' expects a state name"; });
this.states.push(stateName);
return this;
};
Permission.prototype.toString = function () {
return 'Permission Object';
};
/* eslint-disable no-undef */
Permission.EVERYONE = new Permission().everyone();
Permission.AUTHENTICATED = new Permission().authenticated();
return Permission;
}());
exports.Permission = Permission;
var isPermission = function (obj) {
return obj instanceof Permission;
};
exports.isPermission = isPermission;
var isPermissionsArray = function (obj) {
if (util_1.isArray(obj, true)) {
return obj.reduce(function (prev, permission) { return prev && exports.isPermission(permission); }, true);
}
return false;
};
exports.isPermissionsArray = isPermissionsArray;
var findInvalidPermissionAttributes = function (permission, entity) {
var attributes = entity.getAttributes();
permission.userAttributes.map(function (userAttribute) {
var attribute = attributes[userAttribute];
var attributeTypeAsEntity = attribute.type;
var entityAsEntity = entity;
util_1.passOrThrow(attribute &&
(DataTypeUser_1.isDataTypeUser(attribute.type) ||
(entityAsEntity.isUserEntity &&
entityAsEntity.getPrimaryAttribute() === attribute) ||
(Entity_1.isEntity(attribute.type) && attributeTypeAsEntity.isUserEntity)), function () {
return "Cannot use attribute '" + userAttribute + "' in '" + entity.name + ".permissions' as 'userAttribute' as it is not a reference to the User entity";
});
});
};
exports.findInvalidPermissionAttributes = findInvalidPermissionAttributes;
var findMissingPermissionAttributes = function (permission, permissionEntity, mutation) {
var entityAttributeNames = Object.keys(permissionEntity.getAttributes());
var missinguserAttribute = permission.userAttributes.find(function (userAttribute) { return !entityAttributeNames.includes(userAttribute); });
if (missinguserAttribute) {
return missinguserAttribute;
}
var missingLookupAttribute;
permission.lookups.map(function (lookup) {
var _entity = lookup.entity, lookupMap = lookup.lookupMap;
var entity = _entity;
if (util_1.isFunction(_entity)) {
entity = lookup.entity = _entity();
}
var lookupEntityAttributes = entity.getAttributes();
var lookupEntityAttributeNames = Object.keys(lookupEntityAttributes);
_.forEach(lookupMap, function (sourceAttribute, targetAttribute) {
if (!util_1.isFunction(sourceAttribute) &&
!entityAttributeNames.includes(sourceAttribute)) {
missingLookupAttribute = sourceAttribute;
return;
}
else if (!lookupEntityAttributeNames.includes(targetAttribute)) {
missingLookupAttribute = entity.name + "." + targetAttribute;
return;
}
if (Mutation_1.isMutation(mutation) &&
mutation.type === Mutation_1.MUTATION_TYPE_CREATE &&
!util_1.isFunction(sourceAttribute)) {
throw new Error("'lookup' type permission used in 'create' type mutation '" + mutation.name + "' can only have mappings to value functions");
}
});
});
if (missingLookupAttribute) {
return missingLookupAttribute;
}
var missingValueAttribute = permission.values.find(function (_a) {
var attributeName = _a.attributeName;
return !entityAttributeNames.includes(attributeName);
});
if (missingValueAttribute) {
return missingValueAttribute.attributeName;
}
return false;
};
exports.findMissingPermissionAttributes = findMissingPermissionAttributes;
var findMissingPermissionStates = function (permission, permissionEntity) {
var entityStates = permissionEntity.getStates();
if (entityStates) {
var missingState = permission.states.find(function (state) { return !entityStates[state]; });
if (missingState) {
return missingState;
}
}
return false;
};
exports.findMissingPermissionStates = findMissingPermissionStates;
var validateActionLookupPermission = function (permission, permissionAction) {
permission.lookups.map(function (lookup) {
var _entity = lookup.entity, lookupMap = lookup.lookupMap;
var entity = _entity;
if (util_1.isFunction(_entity)) {
entity = lookup.entity = _entity();
}
var lookupEntityAttributes = entity.getAttributes();
var lookupEntityAttributeNames = Object.keys(lookupEntityAttributes);
_.forEach(lookupMap, function (sourceAttribute, targetAttribute) {
util_1.passOrThrow(util_1.isFunction(sourceAttribute), function () {
return "Only functions are allowed in '" + permissionAction.name + ".permissions' for value lookups";
});
util_1.passOrThrow(lookupEntityAttributeNames.includes(targetAttribute), function () {
return "Cannot use attribute '" + targetAttribute + "' in '" + permissionAction.name + ".permissions' as it does not exist";
});
});
});
};
exports.validateActionLookupPermission = validateActionLookupPermission;
var generatePermissionDescription = function (permissions) {
var descriptions = [];
var permissionsArray = util_1.isArray(permissions)
? permissions
: [permissions];
permissionsArray.map(function (permission) {
var lines = [];
util_1.passOrThrow(exports.isPermission(permission), function () { return 'generatePermissionDescription needs a valid permission object'; });
if (permission.everyoneCanAccess) {
lines.push('everyone');
}
if (permission.authenticatedCanAccess) {
lines.push('authenticated');
}
if (permission.roles.length > 0) {
lines.push("roles: " + permission.roles.join(', '));
}
if (permission.userAttributes.length > 0) {
lines.push("userAttributes: " + permission.userAttributes.join(', '));
}
if (permission.states.length > 0) {
lines.push("states: " + permission.states.join(', '));
}
if (permission.lookups.length > 0) {
var lookupBullets = permission.lookups.reduce(function (lprev, _a) {
var entity = _a.entity, lookupMap = _a.lookupMap;
var attributeBullets = _.reduce(lookupMap, function (aprev, target, source) {
return aprev + "\n - " + source + " -> " + (util_1.isFunction(target) ? 'λ' : target);
}, '');
return lprev + "\n - Entity: " + entity + " " + attributeBullets;
}, '');
lines.push("lookups: " + lookupBullets);
}
if (permission.values.length > 0) {
var valueBullets = permission.values.reduce(function (prev, _a) {
var attributeName = _a.attributeName, value = _a.value;
return prev + "\n - " + attributeName + " = " + value;
}, '');
lines.push("values: " + valueBullets);
}
if (lines.length > 0) {
var bullets = lines.reduce(function (prev, next) {
return prev + "\n- " + next;
}, '');
descriptions.push(bullets);
}
});
if (descriptions.length > 0) {
var text = '\n***\n**Permissions:**\n';
return text + descriptions.join('\n\n---');
}
return false;
};
exports.generatePermissionDescription = generatePermissionDescription;
var checkPermissionSimple = function (permission, userId, userRoles) {
if (userId === void 0) { userId = null; }
if (userRoles === void 0) { userRoles = []; }
util_1.passOrThrow(exports.isPermission(permission), function () { return 'checkPermissionSimple needs a valid permission object'; });
util_1.passOrThrow(!userRoles || util_1.isArray(userRoles), function () { return 'checkPermissionSimple needs a valid list of assigned user roles'; });
if (!permission.everyoneCanAccess &&
!permission.authenticatedCanAccess &&
!permission.roles.length) {
return true;
}
if (userId && userRoles) {
var foundRole_1 = false;
permission.roles.map(function (role) {
if (userRoles.includes(role)) {
foundRole_1 = true;
}
});
if (foundRole_1) {
return true;
}
}
if (permission.authenticatedCanAccess && userId && !permission.roles.length) {
return true;
}
if (permission.everyoneCanAccess) {
return true;
}
return false;
};
exports.checkPermissionSimple = checkPermissionSimple;
var isPermissionSimple = function (permission) {
if (!exports.isPermission(permission)) {
throw new Error('isPermissionSimple needs a valid permission object');
}
return (!permission.userAttributes.length &&
!permission.states.length &&
!permission.lookups.length &&
!permission.values.length);
};
exports.isPermissionSimple = isPermissionSimple;
var buildUserAttributesPermissionFilter = function (_a) {
var permission = _a.permission, userId = _a.userId;
var where;
if (permission.userAttributes.length > 0) {
util_1.passOrThrow(userId, function () { return 'missing userId in permission object'; });
where = {};
permission.userAttributes.map(function (attributeName) {
var _a;
var userAttrFilter = (_a = {},
_a[attributeName] = userId,
_a);
if (!where.$or) {
where = { $or: [userAttrFilter] };
}
else {
where.$or.push(userAttrFilter);
}
});
}
return where;
};
exports.buildUserAttributesPermissionFilter = buildUserAttributesPermissionFilter;
var buildStatesPermissionFilter = function (_a) {
var permission = _a.permission, entity = _a.entity;
var where;
if (permission.states.length > 0) {
util_1.passOrThrow(entity, function () { return 'missing entity in permission object'; });
where = {};
var states_1 = entity.getStates();
var stateIds = permission.states.map(function (stateName) {
var state = states_1[stateName];
util_1.passOrThrow(state, function () { return "unknown state name '" + stateName + "' used in permission object"; });
return state;
});
where.$or = [
{
state: {
$in: stateIds,
},
},
];
}
return where;
};
exports.buildStatesPermissionFilter = buildStatesPermissionFilter;
var buildValuesPermissionFilter = function (_a) {
var permission = _a.permission;
var where;
if (permission.values.length > 0) {
where = {};
permission.values.map(function (_a) {
var _b;
var attributeName = _a.attributeName, value = _a.value;
var filter = (_b = {},
_b[attributeName] = value,
_b);
if (!where.$or) {
where = { $or: [filter] };
}
else {
where.$or.push(filter);
}
});
}
return where;
};
exports.buildValuesPermissionFilter = buildValuesPermissionFilter;
var buildLookupsPermissionFilter = function (_a) {
var permission = _a.permission, userId = _a.userId, userRoles = _a.userRoles, input = _a.input, context = _a.context;
return __awaiter(void 0, void 0, void 0, function () {
var where;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(permission.lookups.length > 0)) return [3 /*break*/, 2];
where = {};
return [4 /*yield*/, Promise.all(permission.lookups.map(function (_a) {
var entity = _a.entity, lookupMap = _a.lookupMap;
return __awaiter(void 0, void 0, void 0, function () {
var condition, targetAttributes, filter;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
condition = [];
targetAttributes = Object.keys(lookupMap);
return [4 /*yield*/, Promise.all(targetAttributes.map(function (targetAttribute) { return __awaiter(void 0, void 0, void 0, function () {
var sourceAttribute, operator, value, attr, states_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
sourceAttribute = lookupMap[targetAttribute];
operator = '$eq';
if (!util_1.isFunction(sourceAttribute)) return [3 /*break*/, 2];
return [4 /*yield*/, sourceAttribute({
userId: userId,
userRoles: userRoles,
input: input,
context: context,
})];
case 1:
value = _a.sent();
attr = entity.getAttributes();
if (attr &&
attr[targetAttribute] &&
DataTypeState_1.isDataTypeState(attr[targetAttribute].type)) {
states_2 = entity.getStates();
value = util_1.isArray(value)
? value.map(function (stateName) { return states_2[stateName] || stateName; })
: states_2[value] || value;
}
if (util_1.isArray(value)) {
operator = '$in';
}
condition.push({
targetAttribute: targetAttribute,
operator: operator,
value: value,
});
return [3 /*break*/, 3];
case 2:
condition.push({
targetAttribute: targetAttribute,
operator: operator,
sourceAttribute: sourceAttribute,
});
_a.label = 3;
case 3: return [2 /*return*/];
}
});
}); }))];
case 1:
_b.sent();
filter = {
$sub: {
entity: entity.name,
condition: condition,
},
};
if (!where.$or) {
where.$or = [filter];
}
else {
where.$or.push(filter);
}
return [2 /*return*/];
}
});
});
}))];
case 1:
_b.sent();
_b.label = 2;
case 2: return [2 /*return*/, where];
}
});
});
};
exports.buildLookupsPermissionFilter = buildLookupsPermissionFilter;
var buildPermissionFilterSingle = function (permission, userId, userRoles, entity, input, context) { return __awaiter(void 0, void 0, void 0, function () {
var where, params, permissionFilters, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
params = { permission: permission, userId: userId, userRoles: userRoles, entity: entity, input: input, context: context };
_a = [exports.buildUserAttributesPermissionFilter(params),
exports.buildStatesPermissionFilter(params),
exports.buildValuesPermissionFilter(params)];
return [4 /*yield*/, exports.buildLookupsPermissionFilter(params)];
case 1:
permissionFilters = _a.concat([
_b.sent()
]);
permissionFilters.map(function (permissionFilter) {
if (permissionFilter) {
where = where || {};
// where.$and = where.$and || [];
if (!where.$and) {
where.$and = [permissionFilter];
}
else {
where.$and.push(permissionFilter);
}
}
});
return [2 /*return*/, where];
}
});
}); };
exports.buildPermissionFilterSingle = buildPermissionFilterSingle;
var buildPermissionFilter = function (_permissions, userId, userRoles, entity, input, context) { return __awaiter(void 0, void 0, void 0, function () {
var where, permissions, foundSimplePermission;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!_permissions) {
return [2 /*return*/, where];
}
permissions = util_1.isArray(_permissions)
? _permissions
: [_permissions];
foundSimplePermission = false;
return [4 /*yield*/, util_1.asyncForEach(permissions, function (permission) { return __awaiter(void 0, void 0, void 0, function () {
var initialPass, permissionFilter;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (foundSimplePermission) {
return [2 /*return*/];
}
initialPass = exports.checkPermissionSimple(permission, userId, userRoles);
if (!initialPass) return [3 /*break*/, 2];
// it's a simple permission and permission check passed so let's skip any further checks and give direct access
if (exports.isPermissionSimple(permission)) {
foundSimplePermission = true;
where = {};
return [2 /*return*/];
}
return [4 /*yield*/, exports.buildPermissionFilterSingle(permission, userId, userRoles, entity, input, context)];
case 1:
permissionFilter = _a.sent();
if (permissionFilter) {
where = where || {};
// where.$or = where.$or || [];
if (!where.$or) {
where.$or = [permissionFilter];
}
else {
where.$or.push(permissionFilter);
}
}
_a.label = 2;
case 2: return [2 /*return*/];
}
});
}); })];
case 1:
_a.sent();
return [2 /*return*/, where];
}
});
}); };
exports.buildPermissionFilter = buildPermissionFilter;
var buildActionPermissionFilter = function (_permissions, userId, userRoles, action,
// action: Action,
input, context) {
if (userId === void 0) { userId = null; }
if (userRoles === void 0) { userRoles = []; }
return __awaiter(void 0, void 0, void 0, function () {
var where, lookupPermissionEntity, permissions, permissionFn, permissionResult, foundSimplePermission;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!_permissions) {
// return where;
return [2 /*return*/, undefined];
}
if (util_1.isFunction(_permissions)) {
permissionFn = _permissions;
permissionResult = permissionFn();
permissions = util_1.isArray(permissionResult)
? permissionResult
: [permissionResult];
}
else if (util_1.isArray(_permissions)) {
permissions = _permissions;
}
else {
permissions = [_permissions];
}
foundSimplePermission = false;
return [4 /*yield*/, Promise.all(permissions.map(function (permission) { return __awaiter(void 0, void 0, void 0, function () {
var initialPass, params, permissionFilter;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (foundSimplePermission) {
return [2 /*return*/];
}
initialPass = exports.checkPermissionSimple(permission, userId, userRoles);
if (!initialPass) return [3 /*break*/, 2];
// it's a simple permission and permission check passed so let's skip any further checks and give direct access
if (exports.isPermissionSimple(permission)) {
foundSimplePermission = true;
where = {};
return [2 /*return*/];
}
params = {
permission: permission,
userId: userId,
userRoles: userRoles,
action: action,
input: input,
context: context,
};
return [4 /*yield*/, exports.buildLookupsPermissionFilter(params)];
case 1:
permissionFilter = _a.sent();
if (permissionFilter) {
where = where || {};
// where.$or = where.$or || [];
if (!where.$or) {
where.$or = [permissionFilter];
}
else {
where.$or.push(permissionFilter);
}
lookupPermissionEntity = permission.lookups[0].entity;
}
_a.label = 2;
case 2: return [2 /*return*/];
}
});
}); }))];
case 1:
_a.sent();
return [2 /*return*/, {
where: where,
lookupPermissionEntity: lookupPermissionEntity,
}];
}
});
});
};
exports.buildActionPermissionFilter = buildActionPermissionFilter;
var checkPermissionAdvanced = function (data, permission, userId) {
if (userId === void 0) { userId = null; }
util_1.passOrThrow(exports.isPermission(permission), function () { return 'checkPermissionAdvanced needs a valid permission object'; });
if (permission.userAttributes.length > 0) {
if (!userId) {
return false;
}
var matchesUser = permission.userAttributes.find(function (attributeName) {
return data[attributeName] === userId;
});
return matchesUser;
}
return false;
};
exports.checkPermissionAdvanced = checkPermissionAdvanced;
var validatePermissionAttributesAndStates = function (entity, permissions, _mutation) {
// const permissionsArray = isArray(permissions) ? permissions : [permissions];
var permissionsArray = util_1.isArray(permissions)
? permissions
: [permissions];
var mutation = Mutation_1.isMutation(_mutation) ? _mutation : null;
var mutationAsMutation = _mutation;
var mutationName = Mutation_1.isMutation(_mutation)
? mutationAsMutation.name
: String(_mutation);
permissionsArray.map(function (permission) {
var invalidAttribute = exports.findMissingPermissionAttributes(permission, entity, mutation);
util_1.passOrThrow(!invalidAttribute, function () {
return "Cannot use attribute '" + invalidAttribute + "' in '" + entity.name + ".permissions' for '" + mutationName + "' as it does not exist";
});
exports.findInvalidPermissionAttributes(permission, entity);
var entityAsEntity = entity;
if (entityAsEntity.getStates) {
var invalidState_1 = exports.findMissingPermissionStates(permission, entity);
util_1.passOrThrow(!invalidState_1, function () {
return "Cannot use state '" + invalidState_1 + "' in '" + entity.name + ".permissions' for '" + mutationName + "' as it does not exist";
});
}
});
};
var validatePermissionMutationTypes = function (entity, permissions, mutation) {
if (mutation.type === Mutation_1.MUTATION_TYPE_CREATE) {
// const permissionsArray = isArray(permissions) ? permissions : [permissions];
var permissionsArray = util_1.isArray(permissions)
? permissions
: [permissions];
permissionsArray.map(function (permission) {
util_1.passOrThrow(!permission.userAttributes.length &&
!permission.states.length &&
!permission.values.length, function () {
return "Create type mutation permission '" + mutation.name + "' in '" + entity.name + ".permissions' can only be of type 'authenticated', 'everyone', 'role' or 'lookup'";
});
});
}
};
var validatePermissionSubscriptionTypes = function (entity, permissions, subscription) {
if (subscription.type === Subscription_1.SUBSCRIPTION_TYPE_CREATE) {
var permissionsArray = util_1.isArray(permissions)
? permissions
: [permissions];
permissionsArray.map(function (permission) {
util_1.passOrThrow(!permission.userAttributes.length &&
!permission.states.length &&
!permission.values.length, function () {
return "Create type subscription permission '" + subscription.name + "' in '" + entity.name + ".permissions' can only be of type 'authenticated', 'everyone', 'role' or 'lookup'";
});
});
}
};
var hasEmptyPermissions = function (_permissions) {
if (exports.isPermissionsArray(_permissions)) {
var permissions = _permissions;
var foundEmpty = permissions.find(function (_a) {
var isEmpty = _a.isEmpty;
return isEmpty;
});
return !!foundEmpty;
}
var permission = _permissions;
return permission.isEmpty;
};
exports.hasEmptyPermissions = hasEmptyPermissions;
var findEmptyEntityPermissions = function (permissions) {
var emptyPermissionsIn = [];
if (permissions.read && exports.hasEmptyPermissions(permissions.read)) {
emptyPermissionsIn.push('read');
}
if (permissions.find && exports.hasEmptyPermissions(permissions.find)) {
emptyPermissionsIn.push('find');
}
if (permissions.mutations) {
var mutationNames = Object.keys(permissions.mutations);
mutationNames.map(function (mutationName) {
if (permissions.mutations[mutationName] &&
exports.hasEmptyPermissions(permissions.mutations[mutationName])) {
emptyPermissionsIn.push("mutations." + mutationName);
}
});
}
if (permissions.subscriptions) {
var subscriptionNames = Object.keys(permissions.subscriptions);
subscriptionNames.map(function (subscriptionName) {
if (permissions.subscriptions[subscriptionName] &&
exports.hasEmptyPermissions(permissions.subscriptions[subscriptionName])) {
emptyPermissionsIn.push("subscriptions." + subscriptionName);
}
});
}
return emptyPermissionsIn;
};
exports.findEmptyEntityPermissions = findEmptyEntityPermissions;
var processEntityPermissions = function (entity, permissions, defaultPermissions) {
util_1.passOrThrow(util_1.isMap(permissions), function () {
return "Entity '" + entity.name + "' permissions definition needs to be an object";
});
if (permissions.read) {
util_1.passOrThrow(exports.isPermission(permissions.read) || exports.isPermissionsArray(permissions.read), function () { return "Invalid 'read' permission definition for entity '" + entity.name + "'"; });
}
else if (defaultPermissions) {
permissions.read = defaultPermissions.read;
}
if (permissions.find) {
util_1.passOrThrow(exports.isPermission(permissions.find) || exports.isPermissionsArray(permissions.find), function () { return "Invalid 'find' permission definition for entity '" + entity.name + "'"; });
}
else if (defaultPermissions) {
permissions.find = defaultPermissions.find;
}
var entityMutations = entity.getMutations();
if (!permissions.mutations && defaultPermissions) {
permissions.mutations = {};
}
if (permissions.mutations) {
util_1.passOrThrow(util_1.isMap(permissions.mutations), function () {
return "Entity '" + entity.name + "' permissions definition for mutations needs to be a map of mutations and permissions";
});
var mutationNames = Object.keys(permissions.mutations);
mutationNames.map(function (mutationName, idx) {
util_1.passOrThrow(exports.isPermission(permissions.mutations[mutationName]) ||
exports.isPermissionsArray(permissions.mutations[mutationName]), function () {
return "Invalid mutation permission definition for entity '" + entity.name + "' at position '" + idx + "'";
});
});
if (defaultPermissions) {
entityMutations.map(function (_a) {
var mutationName = _a.name;
if (defaultPermissions.mutations) {
permissions.mutations[mutationName] =
permissions.mutations[mutationName] ||
defaultPermissions.mutations[mutationName] ||
defaultPermissions.mutations._default;
}
});
}
}
var entitySubscriptions = entity.getSubscriptions();
if (!permissions.subscriptions && defaultPermissions) {
permissions.subscriptions = {};
}
if (permissions.subscriptions) {
util_1.passOrThrow(util_1.isMap(permissions.subscriptions), function () {
return "Entity '" + entity.name + "' permissions definition for subscriptions needs to be a map of subscriptions and permissions";
});
var subscriptionNames = Object.keys(permissions.subscriptions);
subscriptionNames.map(function (subscriptionName, idx) {
util_1.passOrThrow(exports.isPermission(permissions.subscriptions[subscriptionName]) ||
exports.isPermissionsArray(permissions.subscriptions[subscriptionName]), function () {
return "Invalid subscription permission definition for entity '" + entity.name + "' at position '" + idx + "'";
});
});
if (defaultPermissions) {
entitySubscriptions.map(function (_a) {
var subscriptionName = _a.name;
if (defaultPermissions.subscriptions) {
permissions.subscriptions[subscriptionName] =
permissions.subscriptions[subscriptionName] ||
defaultPermissions.subscriptions[subscriptionName] ||
defaultPermissions.subscriptions._default;
}
});
}
}
if (permissions.find) {
validatePermissionAttributesAndStates(entity, permissions.find, 'find');
}
if (permissions.read) {
validatePermissionAttributesAndStates(entity, permissions.read, 'read');
}
if (permissions.mutations && entityMutations) {
var permissionMutationNames = Object.keys(permissions.mutations);
var mutationNames_1 = entityMutations.map(function (mutation) { return mutation.name; });
permissionMutationNames.map(function (permissionMutationName) {
util_1.passOrThrow(mutationNames_1.includes(permissionMutationName), function () {
return "Unknown mutation '" + permissionMutationName + "' used for permissions in entity '" + entity.name + "'";
});
});
entityMutations.map(function (mutation) {
var mutationName = mutation.name;
var permission = permissions.mutations[mutationName];
if (permission) {
validatePermissionMutationTypes(entity, permission, mutation);
validatePermissionAttributesAndStates(entity, permission, mutation);
}
});
}
if (permissions.subscriptions && entitySubscriptions) {
var permissionSubscriptionNames = Object.keys(permissions.subscriptions);
var subscriptionNames_1 = entitySubscriptions.map(function (subscription) { return subscription.name; });
permissionSubscriptionNames.map(function (permissionSubscriptionName) {
util_1.passOrThrow(subscriptionNames_1.includes(permissionSubscriptionName), function () {
return "Unknown subscription '" + permissionSubscriptionName + "' used for permissions in entity '" + entity.name + "'";
});
});
entitySubscriptions.map(function (subscription) {
var subscriptionName = subscription.name;
var permission = permissions.subscriptions[subscriptionName];
if (permission) {
// not sure it's needed for subscription
validatePermissionSubscriptionTypes(entity, permission, subscription);
validatePermissionAttributesAndStates(entity, permission, subscription.type);
}
});
}
var emptyPermissionsIn = exports.findEmptyEntityPermissions(permissions);
util_1.passOrThrow(emptyPermissionsIn.length === 0, function () {
return "Entity '" + entity.name + "' has one or more empty permission definitions in: " + emptyPermissionsIn.join(', ');
});
return permissions;
};
exports.processEntityPermissions = processEntityPermissions;
var processViewEntityPermissions = function (entity, permissions, defaultPermissions) {
util_1.passOrThrow(util_1.isMap(permissions), function () {
return "ViewEntity '" + entity.name + "' permissions definition needs to be an object";
});
if (permissions.read) {
util_1.passOrThrow(exports.isPermission(permissions.read) || exports.isPermissionsArray(permissions.read), function () { return "Invalid 'read' permission definition for entity '" + entity.name + "'"; });
}
else if (defaultPermissions) {
permissions.read = defaultPermissions.read;
}
if (permissions.find) {
util_1.passOrThrow(exports.isPermission(permissions.find) || exports.isPermissionsArray(permissions.find), function () { return "Invalid 'find' permission definition for entity '" + entity.name + "'"; });
}
else if (defaultPermissions) {
permissions.find = defaultPermissions.find;
}
if (permissions.find) {
validatePermissionAttributesAndStates(entity, permissions.find, 'find');
}
if (permissions.read) {
validatePermissionAttributesAndStates(entity, permissions.read, 'read');
}
var emptyPermissionsIn = exports.findEmptyEntityPermissions(permissions);
util_1.passOrThrow(emptyPermissionsIn.length === 0, function () {
return "ViewEntity '" + entity.name + "' has one or more empty permission definitions in: " + emptyPermissionsIn.join(', ');
});
return permissions;
};
exports.processViewEntityPermissions = processViewEntityPermissions;
var processActionPermissions = function (action, permissions) {
util_1.passOrThrow(exports.isPermission(permissions) || exports.isPermissionsArray(permissions), function () { return "Invalid permission definition for action '" + action.name + "'"; });
// const permissionsArray = isArray(permissions) ? permissions : [permissions];
var permissionsArray = util_1.isArray(permissions)
? permissions
: [permissions];
permissionsArray.map(function (permission) {
util_1.passOrThrow(!permission.userAttributes.length &&
!permission.values.length &&
!permission.states.length, function () { return "Incompatible permission definition for action '" + action.name + "'"; });
exports.validateActionLookupPermission(permission, action);
});
util_1.passOrThrow(!exports.hasEmptyPermissions(permissions), function () {
return "Action '" + action.name + "' has one or more empty permission definitions";
});
return permissions;
};
exports.processActionPermissions = processActionPermissions;