diff --git a/CHANGELOG.md b/CHANGELOG.md index e3edb60..32a6849 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.1 (September 22nd, 2023) + +- added null checks + ## 1.1.0 (September 20th, 2023) - made all fields optionals in proto files diff --git a/package-lock.json b/package-lock.json index 2e16903..4961de1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@restorecommerce/access-control-srv", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@restorecommerce/access-control-srv", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT", "dependencies": { "@restorecommerce/acs-client": "^1.1.17", diff --git a/package.json b/package.json index adc0ffb..8930ac2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@restorecommerce/access-control-srv", - "version": "1.1.0", + "version": "1.1.1", "description": "Access Control Service", "main": "lib/start.js", "author": "n-fuse GmbH", diff --git a/src/core/accessController.ts b/src/core/accessController.ts index 0fd36aa..e0dc5c0 100644 --- a/src/core/accessController.ts +++ b/src/core/accessController.ts @@ -248,14 +248,14 @@ export class AccessController { } } - if (ruleEffects.length > 0) { + if (ruleEffects?.length > 0) { policyEffects.push(this.decide(policy.combining_algorithm, ruleEffects)); } } } } - if (policyEffects.length > 0) { + if (policyEffects?.length > 0) { effect = this.decide(policySet.combining_algorithm, policyEffects); } } @@ -329,7 +329,7 @@ export class AccessController { // if there are multiple entities in the request.target.resources // and if exactMatch is true, then check again with the resourcesAttributeMatch providing one entity each time // to ensure there is an exact policy entity match for each of the requested entity - if (request?.target?.resources.length > 0 && exactMatch) { + if (request?.target?.resources?.length > 0 && exactMatch) { let noOfEntities = 0; const entityURN = this.urns.get('entity'); for (let resourceAttribute of request.target.resources) { @@ -498,7 +498,7 @@ export class AccessController { let nsEntityArray = pattern?.split('.'); // firstElement could be either entity or namespace let nsOrEntity = nsEntityArray[0]; - let entityRegexValue = nsEntityArray[nsEntityArray.length - 1]; + let entityRegexValue = nsEntityArray[nsEntityArray?.length - 1]; let reqNS, ruleNS; if (nsOrEntity?.toUpperCase() != entityRegexValue?.toUpperCase()) { // rule name space is present @@ -819,7 +819,7 @@ export class AccessController { }); // check in role_associations const userRoleAssocs = context?.subject?.role_associations; - if (userRoleAssocs.length > 0) { + if (userRoleAssocs?.length > 0) { for (let role of userRoleAssocs) { const roleID = role?.role; for (let obj of role.attributes || []) { @@ -839,7 +839,7 @@ export class AccessController { if (!matches && hierarchicalRoleScoping && hierarchicalRoleScoping === 'true') { // check for HR scope const hrScopes = context?.subject?.hierarchical_scopes; - if (!hrScopes || hrScopes.length === 0) { + if (!hrScopes || hrScopes?.length === 0) { return matches; } for (let hrScope of hrScopes || []) { @@ -861,8 +861,8 @@ export class AccessController { } else if (!scopingEntExists) { // scoping entity does not exist - check for point 3. if (context?.subject) { - const userRoleAssocs = context?.subject.role_associations; - if (userRoleAssocs.length > 0) { + const userRoleAssocs = context?.subject?.role_associations; + if (userRoleAssocs?.length > 0) { const ruleSubAttributeObj = ruleSubAttributes?.find((obj) => obj.id === roleURN); for (let obj of userRoleAssocs) { if (obj?.role === ruleSubAttributeObj?.value) { diff --git a/src/core/utils.ts b/src/core/utils.ts index 8a74f91..4b7346b 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -264,7 +264,7 @@ export async function createMetadata(resources: any, }); } - if (resources.length > 0) { + if (resources?.length > 0) { for (let resource of resources) { if (!resource.meta) { resource.meta = {}; @@ -272,10 +272,10 @@ export async function createMetadata(resources: any, if (action === AuthZAction.MODIFY || action === AuthZAction.DELETE) { let result = await service.readMetaData(resource.id); // update owner info - if (result.items.length === 1) { + if (result?.items?.length === 1) { let item = result.items[0].payload; resource.meta.owners = item.meta.owners; - } else if (result.items.length === 0) { + } else if (result?.items?.length === 0) { if (_.isEmpty(resource.id)) { resource.id = uuid.v4().replace(/-/g, ''); } diff --git a/src/core/verifyACL.ts b/src/core/verifyACL.ts index 4819901..66e559a 100644 --- a/src/core/verifyACL.ts +++ b/src/core/verifyACL.ts @@ -48,7 +48,7 @@ export const verifyACLList = async (ruleTarget: Target, } if (ctxResource) { const meta = ctxResource.meta; - if (meta && meta.acls && meta.acls.length > 0) { + if (meta?.acls?.length > 0) { aclList = meta.acls; } } @@ -98,7 +98,7 @@ export const verifyACLList = async (ruleTarget: Target, let subjectScopedEntityInstances = new Map(); let targetScopingEntities = [...targetScopeEntInstances.keys()]; // keys are the scopingEnt - for (let i = 0; i < roleAssociations.length; i += 1) { + for (let i = 0; i < roleAssociations?.length; i += 1) { const role: string = roleAssociations[i]?.role; const attributes: Attribute[] = roleAssociations[i]?.attributes || []; if (scopedRoles.includes(role)) { @@ -205,7 +205,7 @@ export const verifyACLList = async (ruleTarget: Target, } // match atleast one of the subjectOrgInstance is present in targetInstances - if (subjectInstances && subjectInstances.length > 0) { + if (subjectInstances?.length > 0) { for (let subjectInstance of subjectInstances) { // validate atleast one of the subjectInstance is present in the targetInstances list // (same role can be assigned with multiple scoping instnaces hence subjectInstances is an array)