From e501cd5c9e6fecf41920a7e601c8cf5b51b96975 Mon Sep 17 00:00:00 2001 From: akumar Date: Wed, 10 Apr 2024 17:24:26 +0200 Subject: [PATCH 01/10] feat: make scope optional and verify the owner entity and instance with matching role scoping entity and role scoping instance value respectively --- src/core/accessController.ts | 133 +++----------------- src/core/hierarchicalScope.ts | 221 +++++++++++++--------------------- src/core/utils.ts | 22 ---- 3 files changed, 99 insertions(+), 277 deletions(-) diff --git a/src/core/accessController.ts b/src/core/accessController.ts index bda3a4c..4a7a23d 100644 --- a/src/core/accessController.ts +++ b/src/core/accessController.ts @@ -764,136 +764,39 @@ export class AccessController { } /** - * Check if the attributes of subject from a rule, policy - * or policy set match the attributes from a request. + * Check if the Rule's Subject Role matches with atleast + * one of the user role associations role value * * @param ruleAttributes * @param requestSubAttributes + * @param request */ private async checkSubjectMatches(ruleSubAttributes: Attribute[], requestSubAttributes: Attribute[], request: Request): Promise { - // 1) Check if the rule subject entity exists, if so then check - // request->target->subject->orgInst or roleScopeInst matches with - // context->subject->role_associations->roleScopeInst or hierarchical_scope - // 2) if 1 is true then subject match is considered - // 3) If rule subject entity does not exist (as for master data resources) - // then check context->subject->role_associations->role against - // Rule->subject->role - const scopingEntityURN = this.urns.get('roleScopingEntity'); // urn:restorecommerce:acs:names:roleScopingEntity - const scopingInstanceURN = this.urns.get('roleScopingInstance'); // urn:restorecommerce:acs:names:roleScopingInstance - const hierarchicalRoleScopingURN = this.urns.get('hierarchicalRoleScoping'); + // Just check the Role value matches here in subject const roleURN = this.urns.get('role'); - let matches = false; - let scopingEntExists = false; - let ruleRole; - // default if hierarchicalRoleScopingURN is not configured then consider - // to match the HR scopes - let hierarchicalRoleScoping = 'true'; + let ruleRole: string; if (ruleSubAttributes?.length === 0) { - matches = true; - return matches; + return true; } - for (let ruleSubAttribute of ruleSubAttributes || []) { - if (ruleSubAttribute?.id === scopingEntityURN) { - // match the scoping entity value - scopingEntExists = true; - for (let requestSubAttribute of requestSubAttributes || []) { - if (requestSubAttribute?.value === ruleSubAttribute?.value) { - matches = true; - break; - } - } - } else if (ruleSubAttribute?.id === roleURN) { - ruleRole = ruleSubAttribute.value; - } else if (ruleSubAttribute?.id === hierarchicalRoleScopingURN) { - hierarchicalRoleScoping = ruleSubAttribute.value; + ruleSubAttributes?.forEach((subjectObject) => { + if(subjectObject?.id === roleURN) { + ruleRole = subjectObject?.value; } - } + }); - let context = (request as any)?.context as ContextWithSubResolved; - // check if context subject_id contains HR scope if not make request 'createHierarchicalScopes' - if (context?.subject?.token && - _.isEmpty(context.subject.hierarchical_scopes)) { - context = await this.createHRScope(context); + // must be a rule subject targetted to specific user + if (!ruleRole && this.attributesMatch(ruleSubAttributes, requestSubAttributes)) { + this.logger.debug('Rule subject targetted to specific user', ruleSubAttributes); + return true; } - if (scopingEntExists && matches) { - matches = false; - // check the target scoping instance is present in - // the context subject roleassociations and then update matches to true - if (context?.subject?.role_associations) { - let targetScopingInstance; - requestSubAttributes?.find((obj) => { - if (obj?.id === scopingEntityURN && obj?.attributes?.length > 0) { - obj?.attributes?.filter((roleScopeInstObj) => { - if (roleScopeInstObj?.id === scopingInstanceURN) { - targetScopingInstance = roleScopeInstObj?.value; - } - }); - } - }); - // check in role_associations - const userRoleAssocs = context?.subject?.role_associations; - if (userRoleAssocs?.length > 0) { - for (let role of userRoleAssocs) { - const roleID = role?.role; - for (let obj of role.attributes || []) { - if (obj?.id === scopingEntityURN && obj?.attributes?.length > 0) { - for (let ruleScopInstObj of obj.attributes) { - if (ruleScopInstObj?.id == scopingInstanceURN && ruleScopInstObj?.value == targetScopingInstance) { - if (!ruleRole || (ruleRole && ruleRole === roleID)) { - matches = true; - return matches; - } - } - } - } - } - } - } - if (!matches && hierarchicalRoleScoping && hierarchicalRoleScoping === 'true') { - // check for HR scope - const hrScopes = context?.subject?.hierarchical_scopes; - if (!hrScopes || hrScopes?.length === 0) { - return matches; - } - for (let hrScope of hrScopes || []) { - if (this.checkTargetInstanceExists(hrScope, targetScopingInstance)) { - const userRoleAssocs = context?.subject?.role_associations; - if (!_.isEmpty(userRoleAssocs)) { - for (let role of userRoleAssocs || []) { - const roleID = role.role; - if (!ruleRole || (ruleRole && ruleRole === roleID)) { - matches = true; - return matches; - } - } - } - } - } - } - } - } 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 ruleSubAttributeObj = ruleSubAttributes?.find((obj) => obj.id === roleURN); - for (let obj of userRoleAssocs) { - if (obj?.role === ruleSubAttributeObj?.value) { - matches = true; - return matches; - } - } - } - } - // must be a rule subject targetted to specific user - if (!matches && this.attributesMatch(ruleSubAttributes, requestSubAttributes)) { - return true; - } + if(!ruleRole) { + this.logger.warn('Invalid Rule as Rule Subject attributes array contains other id, value pairs without role', ruleSubAttributes); return false; } - return matches; + const context = (request as any)?.context as ContextWithSubResolved; + return context?.subject?.role_associations?.some((roleObj) => roleObj?.role === ruleRole); } private checkTargetInstanceExists(hrScope: HierarchicalScope, diff --git a/src/core/hierarchicalScope.ts b/src/core/hierarchicalScope.ts index ef87b95..24a900e 100644 --- a/src/core/hierarchicalScope.ts +++ b/src/core/hierarchicalScope.ts @@ -6,44 +6,31 @@ import { Request } from '@restorecommerce/rc-grpc-clients/dist/generated-server/ import { Target } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/rule.js'; import { Attribute } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/attribute.js'; import { Resource, ContextWithSubResolved } from './interfaces.js'; -import { getAllValues, updateScopedRoles } from './utils.js'; export const checkHierarchicalScope = async (ruleTarget: Target, request: Request, urns: Map, accessController: AccessController, logger?: Logger): Promise => { - let scopedRoles = new Map>(); // > - let role: string; - const totalScopingEntities: string[] = []; - const ruleSubject = ruleTarget.subjects || []; - let hierarchicalRoleScopeCheck = 'true'; - // retrieving all role scoping entities from the rule's subject - for (let attribute of ruleSubject) { - if (attribute.id == urns.get('role')) { - role = attribute.value; - if (!scopedRoles.has(role)) { - scopedRoles.set(role, new Map()); - } - } - if (attribute.id == urns.get('roleScopingEntity') && !!role) { - const scopingEntity = attribute.value; - - totalScopingEntities.push(scopingEntity); - const scopingEntities = scopedRoles.get(role); - scopingEntities.set(scopingEntity, []); - scopedRoles.set(role, scopingEntities); - role = null; - } - if (attribute.id === urns.get('hierarchicalRoleScoping')) { - hierarchicalRoleScopeCheck = attribute.value; - } - } - - if (_.isEmpty(totalScopingEntities)) { + // 1) create a Map of resourceID with Owners for resource IDs which have the rule entity matching + // 2) In HR scope match validate the Owner indicatory entity with vale from matching users Rule's role for + // matching role scoping enitty with instance + let resourceIdOwnersMap = new Map(); + if (ruleTarget?.subjects?.length === 0) { logger.debug('Scoping entity not found in rule subject hence hierarchical scope check not needed'); return true; // no scoping entities specified in rule, request ignored } + let hierarchicalRoleScopeCheck = 'true'; // default is to check for HR scope for all resources + let ruleRole: string; + const roleURN = urns.get('role'); + ruleTarget?.subjects?.forEach((subjectObject) => { + if (subjectObject?.id === roleURN) { + ruleRole = subjectObject?.value; + } else if (subjectObject?.id === urns.get('hierarchicalRoleScoping')) { + hierarchicalRoleScopeCheck = subjectObject.value; + } + }); let context = (request as any).context as ContextWithSubResolved; if (_.isEmpty(context)) { + logger.debug('Empty context, evaluation fails'); return false; // no context was provided, evaluation fails } @@ -116,7 +103,7 @@ export const checkHierarchicalScope = async (ruleTarget: Target, logger.debug(`Owners information missing for hierarchical scope matching of entity ${attribute.value}, evaluation fails`); return false; // no ownership was passed, evaluation fails } - scopedRoles = updateScopedRoles(meta, scopedRoles, urns, totalScopingEntities); + resourceIdOwnersMap.set(instanceID, meta.owners); } else { logger.debug('Resource of targeted entity was not provided in context'); return false; // resource of targeted entity was not provided in context @@ -137,7 +124,7 @@ export const checkHierarchicalScope = async (ruleTarget: Target, logger.debug(`Owners information missing for hierarchical scope matching of entity ${attribute.value}, evaluation fails`); return false; // no ownership was passed, evaluation fails } - scopedRoles = updateScopedRoles(meta, scopedRoles, urns, totalScopingEntities); + resourceIdOwnersMap.set(entityOrOperation, meta.owners); } else { logger.debug('Operation name was not provided in context'); return false; // Operation name was not provided in context @@ -147,14 +134,8 @@ export const checkHierarchicalScope = async (ruleTarget: Target, } } - if (_.isNil(entityOrOperation) || _.isEmpty(entityOrOperation)) { + if (!entityOrOperation) { logger.debug('No entity or operation name found'); - // return false; // no entity found - } - - // check if context subject_id contains HR scope if not make request 'createHierarchicalScopes' - if (context?.subject?.token && _.isEmpty(context.subject.hierarchical_scopes)) { - context = await accessController.createHRScope(context); } const roleAssociations = context?.subject?.role_associations; @@ -162,116 +143,76 @@ export const checkHierarchicalScope = async (ruleTarget: Target, logger.debug('Role Associations not found'); return false; // impossible to evaluate context } - const treeNodes = new Map>(); // > - for (let i = 0; i < roleAssociations.length; i += 1) { - const role: string = roleAssociations[i].role; - const attributes: Attribute[] = roleAssociations[i].attributes || []; - - if (scopedRoles.has(role)) { - const entities = scopedRoles.get(role); - let scopingEntity: string; - // let roleSubNodes = []; // sub nodes to be queried in case hierarchical resource is not found - for (let attribute of attributes) { - if (attribute.id == urns.get('roleScopingEntity') && entities.has(attribute.value)) { - scopingEntity = attribute.value; - if (attribute?.attributes?.length > 0) { - for (let roleScopeInstObj of attribute.attributes) { // role-attributes-attributes -> roleScopingInstance - if (roleScopeInstObj.id == urns.get('roleScopingInstance') && !!scopingEntity) { // if scoping instance is found within the attributes - const instances = entities.get(scopingEntity); - if (!_.isEmpty(_.remove(instances, (i: string) => i == roleScopeInstObj.value))) { // if any element was removed - if (_.isEmpty(instances)) { - entities.delete(scopingEntity); - if (entities.size == 0) { - scopedRoles.delete(role); - } - } - } else { - if (!treeNodes.has(role)) { - treeNodes.set(role, new Map()); - } - const nodesByEntity = treeNodes.get(role); - if (!nodesByEntity.has(scopingEntity)) { - nodesByEntity.set(scopingEntity, []); - } - const nodes = nodesByEntity.get(scopingEntity); - nodes.push(roleScopeInstObj.value); - nodesByEntity.set(scopingEntity, nodes); - treeNodes.set(role, nodesByEntity); - } - } - } - } - } - } - } - else { - if (i == roleAssociations.length - 1 && scopedRoles.size > 0 && treeNodes.size === 0) { - logger.debug('Subject does not have one of the required roles in its context'); - return false; // user does not have one of the required roles in its context - } + // get all user role association mapping matching the ruleRole -> (Rule Subject's Role) + const reducedUserRoleAssocs = roleAssociations.filter((obj) => obj.role === ruleRole); + + // verify for exact match, if not then verify from HR scopes + let deleteMapEntries = []; + for (let [resourceId, owners] of resourceIdOwnersMap) { + const entityScopingInstMatch = owners?.some((ownerObj) => { + reducedUserRoleAssocs?.some((roleObj) => { + // check if roleScoping Entity matches the Owner's role scoping entity (ex: Organization / User / Klasse etc) + // and check if roleScoping Instance matches with owner instance + roleObj?.attributes?.some((roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') + && ownerObj?.id === urns.get('ownerEntity') && roleAttributeObject?.value === ownerObj?.value + && roleAttributeObject?.attributes?.some((roleInstObj) => + roleInstObj?.id === urns.get('roleScopingInstance') && ownerObj?.attributes?.find((ownerInstObj) => ownerInstObj?.value === roleInstObj?.value))); + }); + }); + if (entityScopingInstMatch) { + // its not safe to remove entries while iterating, so add entries to array to delete later + deleteMapEntries.push(resourceId); } } + deleteMapEntries.forEach((entry) => resourceIdOwnersMap.delete(entry)); - let check = scopedRoles.size == 0; - if (!check && hierarchicalRoleScopeCheck && hierarchicalRoleScopeCheck === 'true') { - const hierarchicalScopes = context.subject.hierarchical_scopes; - for (let hierarchicalScope of hierarchicalScopes) { - let subTreeRole: string = null; - let level = -1; - traverse(hierarchicalScope).forEach(function (node: any): void { // depth-first search - let subtreeFound = false; - if (node.id) { - if (level > -1 && this.level >= level) { - subTreeRole = null; - level = -1; - } else { - if (!subTreeRole) { - for (let [role, nodes] of treeNodes) { - for (let [, instances] of nodes) { - if (_.includes(instances, node.id)) { - subTreeRole = role; - subtreeFound = true; - break; - } - } - } - } - if (subtreeFound) { - const entities = scopedRoles.get(subTreeRole); - let eligibleOrgScopes: string[] = []; - getAllValues(node, eligibleOrgScopes); - if (entities) { - for (let [entity, instances] of entities) { - for (let instance of instances) { - if (eligibleOrgScopes.indexOf(instance) > -1) { - instances = instances.filter(e => e != instance); - } - } - if (instances.length === 0) { - entities.delete(entity); - break; - } - } - } - if (entities && entities.size == 0) { - scopedRoles.delete(subTreeRole); - if (scopedRoles.size == 0) { - check = true; - this.stop(); // stopping traversal, no more scoped roles need to be checked - } - } - // inside hierarchical sub - } + if (resourceIdOwnersMap.size === 0) { + logger.info('Role scoping entities and instances matched'); + return true; + } + + // verify HR scope match + if (resourceIdOwnersMap.size > 0 && hierarchicalRoleScopeCheck === 'true') { + // reset deleteMapEntries + deleteMapEntries = []; + // check if context subject_id contains HR scope if not make request 'createHierarchicalScopes' + if (context?.subject?.token && _.isEmpty(context.subject.hierarchical_scopes)) { + context = await accessController.createHRScope(context); + } + const reducedHRScopes = context?.subject?.hierarchical_scopes?.filter((hrObj) => hrObj?.role === ruleRole); + for (let [resourceId, owners] of resourceIdOwnersMap) { + // validate scoping Entity first + let ownerInstance: string; + const entityMatch = owners?.some((ownerObj) => { + reducedUserRoleAssocs?.some((roleObj) => { + if (roleObj?.attributes?.some((roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') + && ownerObj?.id === urns.get('ownerEntity') && roleAttributeObject?.value === ownerObj?.value)) { + ownerObj?.attributes?.forEach((obj) => ownerInstance = obj.value); + return true; } - } + }); }); + // validate the ownerInstance from HR scope tree for matched scoping entity + if (entityMatch && ownerInstance) { + traverse(reducedHRScopes).forEach((node: any) => { // depth-first search + if (node?.id === ownerInstance) { + deleteMapEntries.push(resourceId); + } + }); + } } + } - if (!check) { - logger.debug('Subject not in HR Scope!'); - } + deleteMapEntries.forEach((entry) => resourceIdOwnersMap.delete(entry)); + + if (resourceIdOwnersMap.size === 0) { + logger.info('Role scoping entities and instances matched from HR scopes'); + return true; } - return check; + if (resourceIdOwnersMap.size > 0) { + logger.debug('Subject not in HR Scope!'); + return false; + } }; diff --git a/src/core/utils.ts b/src/core/utils.ts index a78e66a..bcae261 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -422,25 +422,3 @@ export const flushACSCache = async (userId: string, db_index, commandTopic: Topi await commandTopic.emit('flushCacheCommand', eventObject); logger.info('ACS flush cache command event emitted to kafka topic successfully'); }; - -export const updateScopedRoles = (meta, scopedRoles, urns: Map, totalScopingEntities: string[]): Map> => { - meta.owners.filter((owner) => owner.id === urns.get('ownerEntity') && _.find(totalScopingEntities, e => e === owner.value)).forEach( - (owner) => { - let ownerEntity = owner.value; - owner.attributes.filter(((ownerInstObj) => ownerInstObj.id == urns.get('ownerInstance') && !!ownerEntity)).forEach( - (ownerInstObj) => { - scopedRoles.forEach((entities, role) => { - if (entities.has(ownerEntity)) { - const instances = entities.get(ownerEntity); - instances.push(ownerInstObj.value); - entities.set(ownerEntity, instances); - scopedRoles.set(role, entities); - } - }); - ownerEntity = null; - } - ); - } - ); - return scopedRoles; -}; From cd7123b8b699651fd6e57f7f64f5497aa491bb81 Mon Sep 17 00:00:00 2001 From: akumar Date: Thu, 11 Apr 2024 14:24:14 +0200 Subject: [PATCH 02/10] fix: fixes for matching the owner entity and instances with role scoping entity and instance --- src/core/accessController.ts | 8 ++++++-- src/core/hierarchicalScope.ts | 27 +++++++++++++++++++-------- test/core.spec.ts | 3 ++- test/fixtures/conditions.yml | 5 +---- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/core/accessController.ts b/src/core/accessController.ts index 4a7a23d..f7e8547 100644 --- a/src/core/accessController.ts +++ b/src/core/accessController.ts @@ -776,7 +776,7 @@ export class AccessController { // Just check the Role value matches here in subject const roleURN = this.urns.get('role'); let ruleRole: string; - if (ruleSubAttributes?.length === 0) { + if (!ruleSubAttributes || ruleSubAttributes.length === 0) { return true; } ruleSubAttributes?.forEach((subjectObject) => { @@ -792,10 +792,14 @@ export class AccessController { } if(!ruleRole) { - this.logger.warn('Invalid Rule as Rule Subject attributes array contains other id, value pairs without role', ruleSubAttributes); + this.logger.warn(`Subject does not match with rule attributes`, ruleSubAttributes); return false; } const context = (request as any)?.context as ContextWithSubResolved; + if(!context?.subject?.role_associations) { + this.logger.warn('Subject role associations missing', ruleSubAttributes); + return false; + } return context?.subject?.role_associations?.some((roleObj) => roleObj?.role === ruleRole); } diff --git a/src/core/hierarchicalScope.ts b/src/core/hierarchicalScope.ts index 24a900e..669b426 100644 --- a/src/core/hierarchicalScope.ts +++ b/src/core/hierarchicalScope.ts @@ -14,20 +14,28 @@ export const checkHierarchicalScope = async (ruleTarget: Target, // matching role scoping enitty with instance let resourceIdOwnersMap = new Map(); if (ruleTarget?.subjects?.length === 0) { - logger.debug('Scoping entity not found in rule subject hence hierarchical scope check not needed'); + logger.debug('Rule subject not configured, hence hierarchical scope check not needed'); return true; // no scoping entities specified in rule, request ignored } let hierarchicalRoleScopeCheck = 'true'; // default is to check for HR scope for all resources let ruleRole: string; const roleURN = urns.get('role'); + let ruleRoleScopingEntity: string; // target scoping entity to match from owners and role associations ruleTarget?.subjects?.forEach((subjectObject) => { if (subjectObject?.id === roleURN) { ruleRole = subjectObject?.value; } else if (subjectObject?.id === urns.get('hierarchicalRoleScoping')) { hierarchicalRoleScopeCheck = subjectObject.value; + } else if (subjectObject?.id === urns.get('roleScopingEntity')) { + ruleRoleScopingEntity = subjectObject.value; } }); + if (!ruleRoleScopingEntity) { + logger.debug('Scoping entity not found in rule subject hence hierarchical scope check not needed'); + return true; // no scoping entities specified in rule, request ignored + } + let context = (request as any).context as ContextWithSubResolved; if (_.isEmpty(context)) { logger.debug('Empty context, evaluation fails'); @@ -151,13 +159,15 @@ export const checkHierarchicalScope = async (ruleTarget: Target, let deleteMapEntries = []; for (let [resourceId, owners] of resourceIdOwnersMap) { const entityScopingInstMatch = owners?.some((ownerObj) => { - reducedUserRoleAssocs?.some((roleObj) => { - // check if roleScoping Entity matches the Owner's role scoping entity (ex: Organization / User / Klasse etc) + return reducedUserRoleAssocs?.some((roleObj) => { + // check if Rule's roleScoping Entity matches the Owner's role scoping entity and RoleAssociation RoleScoping entity (ex: Organization / User / Klasse etc) // and check if roleScoping Instance matches with owner instance - roleObj?.attributes?.some((roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') - && ownerObj?.id === urns.get('ownerEntity') && roleAttributeObject?.value === ownerObj?.value + const match = roleObj?.attributes?.some((roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') + && ownerObj?.id === urns.get('ownerEntity') && ownerObj.value === ruleRoleScopingEntity && ownerObj.value === roleAttributeObject?.value && roleAttributeObject?.attributes?.some((roleInstObj) => roleInstObj?.id === urns.get('roleScopingInstance') && ownerObj?.attributes?.find((ownerInstObj) => ownerInstObj?.value === roleInstObj?.value))); + logger.debug('Match result for comparing owner indicatory entity and instance with role scoping entity and instance', { match }); + return match; }); }); if (entityScopingInstMatch) { @@ -185,9 +195,9 @@ export const checkHierarchicalScope = async (ruleTarget: Target, // validate scoping Entity first let ownerInstance: string; const entityMatch = owners?.some((ownerObj) => { - reducedUserRoleAssocs?.some((roleObj) => { + return reducedUserRoleAssocs?.some((roleObj) => { if (roleObj?.attributes?.some((roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') - && ownerObj?.id === urns.get('ownerEntity') && roleAttributeObject?.value === ownerObj?.value)) { + && ownerObj?.id === urns.get('ownerEntity') && ownerObj.value === ruleRoleScopingEntity && ownerObj.value === roleAttributeObject?.value)) { ownerObj?.attributes?.forEach((obj) => ownerInstance = obj.value); return true; } @@ -212,7 +222,8 @@ export const checkHierarchicalScope = async (ruleTarget: Target, } if (resourceIdOwnersMap.size > 0) { - logger.debug('Subject not in HR Scope!'); + const resourceIdOwners = Array.from(resourceIdOwnersMap).map(([resourceId, owners]) => ({ resourceId, owners })); + logger.info('Subject not in HR Scope', resourceIdOwners); return false; } }; diff --git a/test/core.spec.ts b/test/core.spec.ts index fa2eb5d..c06a860 100644 --- a/test/core.spec.ts +++ b/test/core.spec.ts @@ -526,7 +526,8 @@ describe('Testing access control core', () => { ownerIndicatoryEntity: 'urn:restorecommerce:acs:model:organization.Organization', ownerInstance: 'Org1' }); - + // set HR scope for Org2 (since target scope is no longer used since matching is done based on owners with roleAssocs) + (request.context.subject as any).hierarchical_scopes = [{ "id": "Org2", "children": [{ "id": "Org3" }] }]; await requestAndValidate(ac, request, Response_Decision.DENY); }); it('should PERMIT Execute action on executeTestMutation by an Admin', async () => { diff --git a/test/fixtures/conditions.yml b/test/fixtures/conditions.yml index ddc19ed..7e5974a 100644 --- a/test/fixtures/conditions.yml +++ b/test/fixtures/conditions.yml @@ -51,11 +51,8 @@ policy_sets: }) != null;" - id: ruleAA3 name: Rule AA3 - descripton: A rule targeting a user's 'modify' permission regarding a User account + descripton: A fallback rule targeting a user's 'modify' permission regarding a User account target: - subjects: - - id: urn:restorecommerce:acs:names:role - value: SimpleUser resources: - id: urn:restorecommerce:acs:names:model:entity value: urn:restorecommerce:acs:model:user.User From 27513e6db17ebe76a26ac0c0f4fe5d0b9739ca21 Mon Sep 17 00:00:00 2001 From: akumar Date: Thu, 11 Apr 2024 15:19:11 +0200 Subject: [PATCH 03/10] fix: tests as evaluation of whatIsAllowed for reverse policy set query response when target scope is provided is done in acs-client --- src/core/accessController.ts | 15 --------------- test/microservice.spec.ts | 34 +++++++++++++++++++++------------- test/properties.spec.ts | 1 + 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/core/accessController.ts b/src/core/accessController.ts index f7e8547..abbf3ce 100644 --- a/src/core/accessController.ts +++ b/src/core/accessController.ts @@ -803,21 +803,6 @@ export class AccessController { return context?.subject?.role_associations?.some((roleObj) => roleObj?.role === ruleRole); } - private checkTargetInstanceExists(hrScope: HierarchicalScope, - targetScopingInstance: string): boolean { - if (hrScope?.id === targetScopingInstance) { - return true; - } else { - if (hrScope?.children?.length > 0) { - for (let child of hrScope.children) { - if (this.checkTargetInstanceExists(child, targetScopingInstance)) { - return true; - } - } - } - } - } - /** * A list of rules or policies provides a list of Effects. * This method is invoked to evaluate the final effect diff --git a/test/microservice.spec.ts b/test/microservice.spec.ts index 16199ed..9e4e440 100644 --- a/test/microservice.spec.ts +++ b/test/microservice.spec.ts @@ -538,7 +538,7 @@ describe('testing microservice', () => { orgRule.target.actions[0].id.should.equal('urn:oasis:names:tc:xacml:1.0:action:action-id'); orgRule.target.actions[0].value.should.equal('urn:restorecommerce:acs:names:action:read'); }); - it('should return only DENY rules for both Location and Organization resource with resource IDs with invalid target scoping instance', async (): Promise => { + it('should return PERMIT and DENY rules for both Location and Organization resource with resource IDs with invalid target scoping instance', async (): Promise => { const accessRequest = testUtils.buildRequest({ subjectID: 'Alice', subjectRole: 'SimpleUser', @@ -556,23 +556,31 @@ describe('testing microservice', () => { should.exist(result.policy_sets); result.policy_sets.should.be.length(1); + // as evaluation of target scope is done in acs-client for read operations - with returned Reversequery PolicySet read response + // both PERMIT and DENY rules are returned should.exist(result.policy_sets[0].policies); result.policy_sets[0].policies.should.be.length(2); // location and Org Policy result.policy_sets[0].policies[0].id.should.equal('policyA'); result.policy_sets[0].policies[1].id.should.equal('policyB'); should.exist(result.policy_sets[0].policies[0].rules); - result.policy_sets[0].policies[0].rules.should.have.length(1); - result.policy_sets[0].policies[1].rules.should.have.length(1); // ruleAA6 DENY for Organization resource - - // validate Location Deny Rule - const rule = result.policy_sets[0].policies[0].rules[0]; - rule.id.should.equal('ruleAA3'); - rule.effect.should.equal('DENY'); - - // validate Organization Deny Rule - const orgRule = result.policy_sets[0].policies[1].rules[0]; - orgRule.id.should.equal('ruleAA6'); - orgRule.effect.should.equal('DENY'); + result.policy_sets[0].policies[0].rules.should.have.length(2); // ruleAA1 PERMIT and rule AA3 DENY for location resource + result.policy_sets[0].policies[1].rules.should.have.length(2); // ruleAA5 PERMIT and ruleAA6 DENY for Organization resource + + // validate Location Rules + const rule1 = result.policy_sets[0].policies[0].rules[0]; + rule1.id.should.equal('ruleAA1'); + rule1.effect.should.equal('PERMIT'); + const rule2 = result.policy_sets[0].policies[0].rules[1]; + rule2.id.should.equal('ruleAA3'); + rule2.effect.should.equal('DENY'); + + // validate Organization Rules + const rule3 = result.policy_sets[0].policies[1].rules[0]; + rule3.id.should.equal('ruleAA5'); + rule3.effect.should.equal('PERMIT'); + const rule4 = result.policy_sets[0].policies[1].rules[1]; + rule4.id.should.equal('ruleAA6'); + rule4.effect.should.equal('DENY'); }); it('should return only fallback rule when targets don\'t match', async (): Promise => { const accessRequest = testUtils.buildRequest({ diff --git a/test/properties.spec.ts b/test/properties.spec.ts index f759985..df344dd 100644 --- a/test/properties.spec.ts +++ b/test/properties.spec.ts @@ -158,6 +158,7 @@ describe('testing access control', () => { ownerIndicatoryEntity: 'urn:restorecommerce:acs:model:organization.Organization', ownerInstance: ['Org1', 'Org1'] }); + (accessRequest.context.subject as any).hierarchical_scopes = [{ id: 'Org3', children: [] }]; testUtils.marshallRequest(accessRequest); const result = await accessControlService.isAllowed(accessRequest); From 1a1aecd9c8d5636f560c7f9f29fdf7c25eddd3f4 Mon Sep 17 00:00:00 2001 From: akumar Date: Thu, 11 Apr 2024 15:33:11 +0200 Subject: [PATCH 04/10] fix: add tests without setting scope --- test/microservice_acs_enabled.spec.ts | 271 ++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) diff --git a/test/microservice_acs_enabled.spec.ts b/test/microservice_acs_enabled.spec.ts index 1f18650..10b9c80 100644 --- a/test/microservice_acs_enabled.spec.ts +++ b/test/microservice_acs_enabled.spec.ts @@ -381,6 +381,22 @@ describe('testing microservice', () => { should.equal(result.operation_status?.message, 'success'); }); + it('should allow to create test rule with ACS enabled without providing scope in subject', async () => { + // enable authorization + cfg.set('authorization:enabled', true); + cfg.set('authorization:enforce', true); + updateConfig(cfg); + const result = await ruleService.create({ + items: testRule, + subject + }); + should.exist(result); + should.exist(result.items); + should.equal(result.items?.length, testRule.length); + should.equal(result.operation_status?.code, 200); + should.equal(result.operation_status?.message, 'success'); + }); + it('should PERMIT to create 2 test rule with ACS enabled with valid scope in subject and delete them', async () => { let testRule2 = [{ name: '1 test rule for test entitiy', @@ -453,6 +469,77 @@ describe('testing microservice', () => { should.equal(deleteResponse.operation_status?.message, 'success'); }); + it('should PERMIT to create 2 test rule with ACS enabled with out providing scope in subject and delete them', async () => { + let testRule2 = [{ + name: '1 test rule for test entitiy', + description: '1 test rule', + target: { + subjects: [{ + id: 'urn:oasis:names:tc:xacml:1.0:subject:subject-id', + value: 'test-r-id' + }], + resources: [{ + id: 'urn:restorecommerce:acs:names:model:entity', + value: 'urn:restorecommerce:acs:model:test.Test' + }] + }, + effect: Effect.PERMIT, + meta: { + owners: [{ + id: 'urn:restorecommerce:acs:names:ownerIndicatoryEntity', + value: 'urn:restorecommerce:acs:model:organization.Organization', + attributes: [{ + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'orgA' + }] + }] + } + }, { + name: '2 test rule for test entitiy', + description: '2 test rule', + target: { + subjects: [{ + id: 'urn:oasis:names:tc:xacml:1.0:subject:subject-id', + value: 'test-r-id' + }], + resources: [{ + id: 'urn:restorecommerce:acs:names:model:entity', + value: 'urn:restorecommerce:acs:model:test.Test' + }] + }, + effect: Effect.PERMIT, + meta: { + owners: [{ + id: 'urn:restorecommerce:acs:names:ownerIndicatoryEntity', + value: 'urn:restorecommerce:acs:model:organization.Organization', + attributes: [{ + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'orgB' + }] + }] + } + }]; + const result = await ruleService.create({ + items: testRule2, + subject + }); + should.exist(result); + should.exist(result.items); + should.equal(result.items?.length, testRule2.length); + should.equal(result.operation_status?.code, 200); + should.equal(result.operation_status?.message, 'success'); + const deleteResponse = await ruleService.delete( + { + ids: result.items?.map(i => i.payload?.id ?? ''), + subject + } + ); + should.equal(deleteResponse.status?.[0].id, result.items?.[0].payload?.id); + should.equal(deleteResponse.status?.[1].id, result.items?.[1].payload?.id); + should.equal(deleteResponse.operation_status?.code, 200); + should.equal(deleteResponse.operation_status?.message, 'success'); + }); + it('should DENY to create 2 test rule with ACS enabled with valid scope in subject and valid owner for 1st instance and invalid owner for 2nd instance', async () => { let testRule2 = [{ name: '1 test rule for test entitiy', @@ -516,6 +603,68 @@ describe('testing microservice', () => { ); }); + it('should DENY to create 2 test rule with ACS enabled without providing scope in subject and valid owner for 1st instance and invalid owner for 2nd instance', async () => { + let testRule2 = [{ + name: '1 test rule for test entitiy', + description: '1 test rule', + target: { + subjects: [{ + id: 'urn:oasis:names:tc:xacml:1.0:subject:subject-id', + value: 'test-r-id' + }], + resources: [{ + id: 'urn:restorecommerce:acs:names:model:entity', + value: 'urn:restorecommerce:acs:model:test.Test' + }] + }, + effect: Effect.PERMIT, + meta: { + owners: [{ + id: 'urn:restorecommerce:acs:names:ownerIndicatoryEntity', + value: 'urn:restorecommerce:acs:model:organization.Organization', + attributes: [{ + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'orgA' + }] + }] + } + }, { + name: '2 test rule for test entitiy', + description: '2 test rule', + target: { + subjects: [{ + id: 'urn:oasis:names:tc:xacml:1.0:subject:subject-id', + value: 'test-r-id' + }], + resources: [{ + id: 'urn:restorecommerce:acs:names:model:entity', + value: 'urn:restorecommerce:acs:model:test.Test' + }] + }, + effect: Effect.PERMIT, + meta: { + owners: [{ + id: 'urn:restorecommerce:acs:names:ownerIndicatoryEntity', + value: 'urn:restorecommerce:acs:model:organization.Organization', + attributes: [{ + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'INVALID' // invalid owner org instance + }] + }] + } + }]; + const result = await ruleService.create({ + items: testRule2, + subject + }); + should.not.exist(result.items); + should.equal(result.operation_status?.code, 403); + should.equal( + result.operation_status?.message, + 'Access not allowed for request with subject:admin_user_id, resource:rule, action:CREATE, target_scope:orgA; the response was DENY' + ); + }); + it('should throw an error when trying to create rule with invalid subject scope', async () => { // change subject to normal user subject.id = 'user_id'; @@ -546,6 +695,35 @@ describe('testing microservice', () => { ); }); + it('should throw an error when trying to create rule with out providing scope in subject', async () => { + // change subject to normal user + subject.id = 'user_id'; + subject.role_associations[0].role = 'user-r-id'; + subject.token = 'user_token'; + const user = { + payload: { + id: subject.id, + tokens: [{ token: 'user_token' }], + role_associations: subject.role_associations + }, + status: { + code: 200, + message: 'success' + } + }; + const result = await ruleService.create({ + items: testRule, + subject + }); + should.exist(result); + should.not.exist(result.items); + should.equal(result.operation_status?.code, 403); + should.equal( + result.operation_status?.message, + 'Access not allowed for request with subject:user_id, resource:rule, action:CREATE, target_scope:orgC; the response was DENY' + ); + }); + it('should allow to update rule with valid subject scope', async () => { // change subject to admin user subject.id = 'admin_user_id'; @@ -776,6 +954,99 @@ describe('testing microservice', () => { should.equal(result2.operation_status?.code, 200); should.equal(result2.operation_status?.message, 'success'); }); + + // Create with two different scopes assigned for same role + it('should PERMIT to create test rule with ACS enabled without providing scope in subject with multilple instances assigned to same role', async () => { + let testRule1 = [{ + name: '1 test rule for test entitiy', + description: '1 test rule', + target: { + subjects: [{ + id: 'urn:oasis:names:tc:xacml:1.0:subject:subject-id', + value: 'test-r-id' + }], + resources: [{ + id: 'urn:restorecommerce:acs:names:model:entity', + value: 'urn:restorecommerce:acs:model:test.Test' + }] + }, + effect: Effect.PERMIT, + meta: { + owners: [{ + id: 'urn:restorecommerce:acs:names:ownerIndicatoryEntity', + value: 'urn:restorecommerce:acs:model:organization.Organization', + attributes: [{ + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'org1' + }] + }] + } + }]; + // For admin-r-id role Assign two RoleScoped instances (Same Role with 2 different scopes assigned) + adminSubject.role_associations[0].attributes[0].attributes = [{ + id: 'urn:restorecommerce:acs:names:roleScopingInstance', + value: 'org1' + }, { + id: 'urn:restorecommerce:acs:names:roleScopingInstance', + value: 'org2' + }]; + // corresponding HR scopes for two different Orgs + adminSubject.hierarchical_scopes = [{ + id: 'org1', + role: 'admin-r-id', + children: [] + }, { + id: 'org2', + role: 'admin-r-id', + children: [] + }]; + + const result = await ruleService.create({ + items: testRule1, + subject: adminSubject + }); + // validate result + should.equal(result.items?.length, 1); + should.equal(result.items?.[0]?.payload?.name, '1 test rule for test entitiy'); + should.equal(result.operation_status?.code, 200); + should.equal(result.operation_status?.message, 'success'); + + let testRule2 = [{ + name: '2 test rule for test entitiy', + description: '2 test rule', + target: { + subjects: [{ + id: 'urn:oasis:names:tc:xacml:1.0:subject:subject-id', + value: 'test-r-id' + }], + resources: [{ + id: 'urn:restorecommerce:acs:names:model:entity', + value: 'urn:restorecommerce:acs:model:test.Test' + }] + }, + effect: Effect.PERMIT, + meta: { + owners: [{ + id: 'urn:restorecommerce:acs:names:ownerIndicatoryEntity', + value: 'urn:restorecommerce:acs:model:organization.Organization', + attributes: [{ + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'org2' + }] + }] + } + }]; + + const result2 = await ruleService.create({ + items: testRule2, + subject: adminSubject + }); + // validate result2 + should.equal(result2.items?.length, 1); + should.equal(result2.items?.[0]?.payload?.name, '2 test rule for test entitiy'); + should.equal(result2.operation_status?.code, 200); + should.equal(result2.operation_status?.message, 'success'); + }); }); }); }); From 1de3f872a811e39461d04b42ece672cc53625381 Mon Sep 17 00:00:00 2001 From: akumar Date: Thu, 11 Apr 2024 15:41:12 +0200 Subject: [PATCH 05/10] chore: up doc --- docs/modules/ROOT/pages/abac.adoc | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/docs/modules/ROOT/pages/abac.adoc b/docs/modules/ROOT/pages/abac.adoc index 6fd60a2..deade9b 100644 --- a/docs/modules/ROOT/pages/abac.adoc +++ b/docs/modules/ROOT/pages/abac.adoc @@ -93,11 +93,7 @@ as demanding such evaluation would require a replication of this functionality a - id ex: urn:oasis:names:tc:xacml:1.0:subject:subject-id - value ex: - # To identify role scoping entity - - id ex: urn:restorecommerce:acs:names:roleScopingEntity - - value ex: urn:restorecommerce:acs:model:organization.Organization - - # To identify role scoping instance + # To identify role scoping instance (optional) - id ex: urn:restorecommerce:acs:names:roleScopeInstance value: ex: - resources @@ -190,10 +186,6 @@ request: subjects: - id: ex: urn:oasis:names:tc:xacml:1.0:subject:subject-id value: Alice - - id: urn:restorecommerce:acs:names:roleScopingEntity - value: urn:restorecommerce:acs:model:organization.Organization - - id: urn:restorecommerce:acs:names:roleScopeInstance - value: OrgB resources: - id: urn:restorecommerce:acs:names:model:entity value: urn:restorecommerce:model:device.Device @@ -283,7 +275,8 @@ which according to the policy's combining algorithm means access should be grant The operation `whatIsAllowed` is used when there is not a specific target resource for a request, for example, when Subject aims to see as much resources as possible. This example illustrates permissible actions on two resource entities `Address` and `Country` for Subject `Alice` who has the role `admin` within the scoping entity -`Organization` with ID 'OrgA'. +`Organization` with ID 'OrgA'. The target role scoping instance in subjects below `OrgA` is optional for `whatIsAllowed`, if it is provided then filters are created by https://github.com/restorecommerce/libs/tree/next/packages/acs-client[`acs-client`] based on +this target role scope instance if not all applicable filters are returned from `acs-client` [source,yml] ---- @@ -292,8 +285,6 @@ request: subjects: - id: ex: urn:oasis:names:tc:xacml:1.0:subject:subject-id value: Alice - - id: urn:restorecommerce:acs:names:roleScopingEntity - value: urn:restorecommerce:acs:model:organization.Organization - id: urn:restorecommerce:acs:names:roleScopeInstance value: OrgA resources: @@ -394,8 +385,6 @@ request: subjects: - id: ex: urn:oasis:names:tc:xacml:1.0:subject:subject-id value: Alice - - id: urn:restorecommerce:acs:names:roleScopingEntity - value: urn:restorecommerce:acs:model:organization.Organization - id: urn:restorecommerce:acs:names:roleScopeInstance value: OrgA resources: From e6c5f551a5f336d49e77d48cde39bcc76bf27aea Mon Sep 17 00:00:00 2001 From: akumar Date: Thu, 11 Apr 2024 17:16:16 +0200 Subject: [PATCH 06/10] fix: handle multiple owners for single entity for owners in HR scope matching --- src/core/hierarchicalScope.ts | 8 ++++---- test/microservice_acs_enabled.spec.ts | 14 +++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/hierarchicalScope.ts b/src/core/hierarchicalScope.ts index 669b426..d25fc69 100644 --- a/src/core/hierarchicalScope.ts +++ b/src/core/hierarchicalScope.ts @@ -193,20 +193,20 @@ export const checkHierarchicalScope = async (ruleTarget: Target, const reducedHRScopes = context?.subject?.hierarchical_scopes?.filter((hrObj) => hrObj?.role === ruleRole); for (let [resourceId, owners] of resourceIdOwnersMap) { // validate scoping Entity first - let ownerInstance: string; + let ownerInstances: string[] = []; const entityMatch = owners?.some((ownerObj) => { return reducedUserRoleAssocs?.some((roleObj) => { if (roleObj?.attributes?.some((roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') && ownerObj?.id === urns.get('ownerEntity') && ownerObj.value === ruleRoleScopingEntity && ownerObj.value === roleAttributeObject?.value)) { - ownerObj?.attributes?.forEach((obj) => ownerInstance = obj.value); + ownerObj?.attributes?.forEach((obj) => ownerInstances.push(obj.value)); return true; } }); }); // validate the ownerInstance from HR scope tree for matched scoping entity - if (entityMatch && ownerInstance) { + if (entityMatch && ownerInstances?.length > 0) { traverse(reducedHRScopes).forEach((node: any) => { // depth-first search - if (node?.id === ownerInstance) { + if (ownerInstances.includes(node?.id)) { deleteMapEntries.push(resourceId); } }); diff --git a/test/microservice_acs_enabled.spec.ts b/test/microservice_acs_enabled.spec.ts index 10b9c80..9560245 100644 --- a/test/microservice_acs_enabled.spec.ts +++ b/test/microservice_acs_enabled.spec.ts @@ -956,7 +956,7 @@ describe('testing microservice', () => { }); // Create with two different scopes assigned for same role - it('should PERMIT to create test rule with ACS enabled without providing scope in subject with multilple instances assigned to same role', async () => { + it('should PERMIT to create test rule with ACS enabled with multiple owners without providing scope in subject with multilple instances assigned to same role', async () => { let testRule1 = [{ name: '1 test rule for test entitiy', description: '1 test rule', @@ -978,6 +978,12 @@ describe('testing microservice', () => { attributes: [{ id: 'urn:restorecommerce:acs:names:ownerInstance', value: 'org1' + }, { + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'org2' + }, { + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'org3' }] }] } @@ -1030,8 +1036,14 @@ describe('testing microservice', () => { id: 'urn:restorecommerce:acs:names:ownerIndicatoryEntity', value: 'urn:restorecommerce:acs:model:organization.Organization', attributes: [{ + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'org1' + }, { id: 'urn:restorecommerce:acs:names:ownerInstance', value: 'org2' + }, { + id: 'urn:restorecommerce:acs:names:ownerInstance', + value: 'org3' }] }] } From f06da83c84ec630e5fe21d7e277f31bca30ff153 Mon Sep 17 00:00:00 2001 From: akumar Date: Fri, 12 Apr 2024 11:41:15 +0200 Subject: [PATCH 07/10] fix: use flatmap to get ownerInstances in HR scoping --- src/core/hierarchicalScope.ts | 36 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/core/hierarchicalScope.ts b/src/core/hierarchicalScope.ts index d25fc69..3273fda 100644 --- a/src/core/hierarchicalScope.ts +++ b/src/core/hierarchicalScope.ts @@ -192,25 +192,31 @@ export const checkHierarchicalScope = async (ruleTarget: Target, } const reducedHRScopes = context?.subject?.hierarchical_scopes?.filter((hrObj) => hrObj?.role === ruleRole); for (let [resourceId, owners] of resourceIdOwnersMap) { - // validate scoping Entity first - let ownerInstances: string[] = []; - const entityMatch = owners?.some((ownerObj) => { - return reducedUserRoleAssocs?.some((roleObj) => { - if (roleObj?.attributes?.some((roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') - && ownerObj?.id === urns.get('ownerEntity') && ownerObj.value === ruleRoleScopingEntity && ownerObj.value === roleAttributeObject?.value)) { - ownerObj?.attributes?.forEach((obj) => ownerInstances.push(obj.value)); - return true; - } - }); - }); + const ownerInstances: string[] = owners.filter( + owner => reducedUserRoleAssocs?.some((roleObj) => { + return roleObj?.attributes?.some( + (roleAttributeObject) => roleAttributeObject?.id === urns.get('roleScopingEntity') + && owner?.id === urns.get('ownerEntity') + && owner?.value === ruleRoleScopingEntity + && owner?.value === roleAttributeObject?.value + ); + } + ) + ).flatMap( + owner => owner?.attributes?.filter( + attr => attr?.id === urns.get('ownerInstance') + ).map( + attr => attr?.value + ) + ); // validate the ownerInstance from HR scope tree for matched scoping entity - if (entityMatch && ownerInstances?.length > 0) { - traverse(reducedHRScopes).forEach((node: any) => { // depth-first search + traverse(reducedHRScopes).forEach( + (node: any) => { // depth-first search if (ownerInstances.includes(node?.id)) { deleteMapEntries.push(resourceId); } - }); - } + } + ); } } From da1b32e69c390854779e0f4f68452c4cdfe9e70b Mon Sep 17 00:00:00 2001 From: akumar Date: Fri, 12 Apr 2024 11:50:12 +0200 Subject: [PATCH 08/10] fix: removed redundant target scoping entity and target scoping instance from ACS request message --- test/utils.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test/utils.ts b/test/utils.ts index ba43cad..ad19ba2 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -37,20 +37,6 @@ export const buildRequest = (opts: RequestOpts): Request => { } ]); - if (opts.roleScopingEntity && opts.roleScopingInstance) { - subjects = subjects.concat([ - { - id: 'urn:restorecommerce:acs:names:roleScopingEntity', - value: opts.roleScopingEntity, - attributes: [{ - id: 'urn:restorecommerce:acs:names:roleScopingInstance', - value: opts.targetScopingInstance ? opts.targetScopingInstance : opts.roleScopingInstance, - attributes: [] - }] - } - ]); - } - if (opts.actionType === 'urn:restorecommerce:acs:names:action:execute') { if (typeof opts.resourceType === 'string') { resources = resources.concat([ From 532befec7a64735979f5642bb40d08342f88f190 Mon Sep 17 00:00:00 2001 From: akumar Date: Fri, 12 Apr 2024 15:18:44 +0200 Subject: [PATCH 09/10] fix: fix subject with HR scope matching on Policy target --- src/core/accessController.ts | 16 ++++++++--- test/core.spec.ts | 32 ++++++++++++++++++++++ test/fixtures/policy_sets_with_targets.yml | 27 ++++++++++++++++++ 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/core/accessController.ts b/src/core/accessController.ts index abbf3ce..5059724 100644 --- a/src/core/accessController.ts +++ b/src/core/accessController.ts @@ -178,6 +178,14 @@ export class AccessController { ) { const rules: Map = policy.combinables; this.logger.verbose(`Checking policy ${policy.name}`); + let policySubjectMatch: boolean; + // Subject set on Policy validate HR scope matching + if (policy?.target?.subjects?.length > 0) { + this.logger.verbose(`Checking Policy subject HR Scope match for ${policy.name}`); + policySubjectMatch = await checkHierarchicalScope(policy.target, request, this.urns, this, this.logger); + } else { + policySubjectMatch = true; + } // only apply a policy effect if there are no rules // combine rules otherwise if (rules.size == 0 && !!policy.effect) { @@ -259,7 +267,7 @@ export class AccessController { matches = await verifyACLList(rule.target, request, this.urns, this, this.logger); } - if (matches) { + if (matches && policySubjectMatch) { if (!evaluationCacheableRule) { evaluation_cacheable = evaluationCacheableRule; } @@ -780,7 +788,7 @@ export class AccessController { return true; } ruleSubAttributes?.forEach((subjectObject) => { - if(subjectObject?.id === roleURN) { + if (subjectObject?.id === roleURN) { ruleRole = subjectObject?.value; } }); @@ -791,12 +799,12 @@ export class AccessController { return true; } - if(!ruleRole) { + if (!ruleRole) { this.logger.warn(`Subject does not match with rule attributes`, ruleSubAttributes); return false; } const context = (request as any)?.context as ContextWithSubResolved; - if(!context?.subject?.role_associations) { + if (!context?.subject?.role_associations) { this.logger.warn('Subject role associations missing', ruleSubAttributes); return false; } diff --git a/test/core.spec.ts b/test/core.spec.ts index c06a860..f3e62f1 100644 --- a/test/core.spec.ts +++ b/test/core.spec.ts @@ -368,6 +368,38 @@ describe('Testing access control core', () => { await requestAndValidate(ac, request, Response_Decision.PERMIT); }); + it('should INDETERMINATE based on rule R6 as subject HR scope does not match', async () => { + request = testUtils.buildRequest({ + subjectID: 'Alice', + subjectRole: 'SimpleUser', + roleScopingEntity: 'urn:restorecommerce:acs:model:organization.Organization', + roleScopingInstance: 'Org1', + resourceType: 'urn:restorecommerce:acs:model:location.Location', + resourceID: 'Random', + actionType: 'urn:restorecommerce:acs:names:action:modify', + ownerIndicatoryEntity: 'urn:restorecommerce:acs:model:organization.Organization', + ownerInstance: 'Org4' // does not exist in HR scope + }); + + await requestAndValidate(ac, request, Response_Decision.INDETERMINATE); + }); + + it('should PERMIT based on rule R6 as subject HR scope matches', async () => { + request = testUtils.buildRequest({ + subjectID: 'Alice', + subjectRole: 'SimpleUser', + roleScopingEntity: 'urn:restorecommerce:acs:model:organization.Organization', + roleScopingInstance: 'Org1', + resourceType: 'urn:restorecommerce:acs:model:location.Location', + resourceID: 'Random', + actionType: 'urn:restorecommerce:acs:names:action:modify', + ownerIndicatoryEntity: 'urn:restorecommerce:acs:model:organization.Organization', + ownerInstance: 'Org2' // exist in HR scope + }); + + await requestAndValidate(ac, request, Response_Decision.PERMIT); + }); + it('should DENY based on Rule BA2', async () => { request = testUtils.buildRequest({ subjectID: 'External Bob', diff --git a/test/fixtures/policy_sets_with_targets.yml b/test/fixtures/policy_sets_with_targets.yml index d28cff2..cd5337f 100644 --- a/test/fixtures/policy_sets_with_targets.yml +++ b/test/fixtures/policy_sets_with_targets.yml @@ -80,3 +80,30 @@ policy_sets: - id: urn:oasis:names:tc:xacml:1.0:action:action-id value: urn:restorecommerce:acs:names:action:read effect: PERMIT + - id: PS3 + name: 'Policy set C' + description: 'A policy set targeting Org scoping with Subject scoping defined on Policy level instead of Rule' + combining_algorithm: urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides + policies: + - id: P3 + name: Policy with Org Scoping for Location Resource + description: A Policy targeting access for Org scope users for Location resource + combining_algorithm: urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides + target: + subjects: + - id: urn:restorecommerce:acs:names:role + value: SimpleUser + - id: urn:restorecommerce:acs:names:roleScopingEntity + value: urn:restorecommerce:acs:model:organization.Organization + resources: + - id: urn:restorecommerce:acs:names:model:entity + value: urn:restorecommerce:acs:model:location.Location + rules: + - id: R6 + name: Rule 5 + description: A rule targeting 'modify' actions on Location resource + target: + actions: + - id: urn:oasis:names:tc:xacml:1.0:action:action-id + value: urn:restorecommerce:acs:names:action:modify + effect: PERMIT From f5322d43dd1d23c2584eb5ec06f7240e45575e0a Mon Sep 17 00:00:00 2001 From: akumar Date: Tue, 16 Apr 2024 12:54:49 +0200 Subject: [PATCH 10/10] chore: up deps --- package-lock.json | 765 ++++++++++++++++++++++++++-------------------- package.json | 34 +-- 2 files changed, 445 insertions(+), 354 deletions(-) diff --git a/package-lock.json b/package-lock.json index f513045..3201e7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,13 @@ "version": "1.2.8", "license": "MIT", "dependencies": { - "@restorecommerce/acs-client": "^1.4.15", - "@restorecommerce/chassis-srv": "^1.4.9", - "@restorecommerce/grpc-client": "^2.2.0", - "@restorecommerce/kafka-client": "^1.1.23", + "@restorecommerce/acs-client": "^1.5.1", + "@restorecommerce/chassis-srv": "^1.5.0", + "@restorecommerce/grpc-client": "^2.2.1", + "@restorecommerce/kafka-client": "^1.2.1", "@restorecommerce/logger": "^1.2.10", - "@restorecommerce/rc-grpc-clients": "^5.1.22", - "@restorecommerce/resource-base-interface": "^1.4.8", + "@restorecommerce/rc-grpc-clients": "^5.1.23", + "@restorecommerce/resource-base-interface": "^1.5.0", "@restorecommerce/service-config": "^1.0.12", "apollo-boost": "^0.4.9", "apollo-cache-inmemory": "^1.6.6", @@ -26,23 +26,23 @@ "js-yaml": "^4.1.0", "lodash-es": "^4.17.21", "node-eval": "^2.0.0", - "traverse": "^0.6.8" + "traverse": "^0.6.9" }, "devDependencies": { - "@alenon/grpc-mock-server": "^3.1.9", - "@commitlint/cli": "^19.2.1", - "@commitlint/config-conventional": "^19.1.0", - "@grpc/proto-loader": "^0.7.10", + "@alenon/grpc-mock-server": "^3.1.10", + "@commitlint/cli": "^19.2.2", + "@commitlint/config-conventional": "^19.2.2", + "@grpc/proto-loader": "^0.7.12", "@restorecommerce/dev": "^0.0.9", - "@restorecommerce/protos": "^6.8.0", + "@restorecommerce/protos": "^6.8.1", "@semantic-release-plus/docker": "^3.1.3", "@types/lodash-es": "^4.17.12", "@types/mocha": "^10.0.6", "@types/nock": "^11.1.0", - "@types/node": "^20.11.29", - "@typescript-eslint/eslint-plugin": "^7.3.1", + "@types/node": "^20.12.7", + "@typescript-eslint/eslint-plugin": "^7.7.0", "@typescript-eslint/eslint-plugin-tslint": "^7.0.2", - "@typescript-eslint/parser": "^7.3.1", + "@typescript-eslint/parser": "^7.7.0", "c8": "^9.1.0", "coveralls": "^3.1.1", "cross-env": "^7.0.3", @@ -51,7 +51,7 @@ "eslint": "^8.57.0", "eslint-plugin-prefer-arrow-functions": "^3.3.2", "husky": "^9.0.11", - "mocha": "^10.3.0", + "mocha": "^10.4.0", "nock": "^13.5.4", "nodemon": "^3.1.0", "npm-run-all": "^4.1.5", @@ -59,7 +59,7 @@ "should": "^13.2.3", "ts-node": "^10.9.2", "tslint": "^6.1.3", - "typescript": "^5.4.2" + "typescript": "^5.4.5" }, "engines": { "node": ">= 20.8.0" @@ -75,12 +75,12 @@ } }, "node_modules/@alenon/grpc-mock-server": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@alenon/grpc-mock-server/-/grpc-mock-server-3.1.9.tgz", - "integrity": "sha512-HoSsprlUwi1xjS9+dlRaJX6uafBYy68zGkmO+9KzaQYuqpSwszS27e8Mx31k6ArjIgTzXntAlOmQXZSJjGoT8A==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@alenon/grpc-mock-server/-/grpc-mock-server-3.1.10.tgz", + "integrity": "sha512-MS26o7xy9iiSQ2p7jd5BieWlAymjoCl+aCd7lFRgUVxXp7vSzqht5D57LiVCqo6FeU0w0VuJgqabCm7qIQbhRA==", "dev": true, "dependencies": { - "@grpc/grpc-js": "1.10.0", + "@grpc/grpc-js": "1.10.6", "@types/debug": "^4.1.8", "@types/google-protobuf": "^3.15.12", "@types/node": "^20.5.9", @@ -282,13 +282,13 @@ } }, "node_modules/@commitlint/cli": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.2.1.tgz", - "integrity": "sha512-cbkYUJsLqRomccNxvoJTyv5yn0bSy05BBizVyIcLACkRbVUqYorC351Diw/XFSWC/GtpwiwT2eOvQgFZa374bg==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.2.2.tgz", + "integrity": "sha512-P8cbOHfg2PQRzfICLSrzUVOCVMqjEZ8Hlth6mtJ4yOEjT47Q5PbIGymgX3rLVylNw+3IAT2Djn9IJ2wHbXFzBg==", "dev": true, "dependencies": { "@commitlint/format": "^19.0.3", - "@commitlint/lint": "^19.1.0", + "@commitlint/lint": "^19.2.2", "@commitlint/load": "^19.2.0", "@commitlint/read": "^19.2.1", "@commitlint/types": "^19.0.3", @@ -425,9 +425,9 @@ } }, "node_modules/@commitlint/config-conventional": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.1.0.tgz", - "integrity": "sha512-KIKD2xrp6Uuk+dcZVj3++MlzIr/Su6zLE8crEDQCZNvWHNQSeeGbzOlNtsR32TUy6H3JbP7nWgduAHCaiGQ6EA==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", + "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -524,9 +524,9 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.0.3.tgz", - "integrity": "sha512-MqDrxJaRSVSzCbPsV6iOKG/Lt52Y+PVwFVexqImmYYFhe51iVJjK2hRhOG2jUAGiUHk4jpdFr0cZPzcBkSzXDQ==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", + "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -537,12 +537,12 @@ } }, "node_modules/@commitlint/lint": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.1.0.tgz", - "integrity": "sha512-ESjaBmL/9cxm+eePyEr6SFlBUIYlYpI80n+Ltm7IA3MAcrmiP05UMhJdAD66sO8jvo8O4xdGn/1Mt2G5VzfZKw==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", + "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^19.0.3", + "@commitlint/is-ignored": "^19.2.2", "@commitlint/parse": "^19.0.3", "@commitlint/rules": "^19.0.3", "@commitlint/types": "^19.0.3" @@ -1591,9 +1591,9 @@ } }, "node_modules/@grpc/proto-loader": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", - "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.12.tgz", + "integrity": "sha512-DCVwMxqYzpUCiDMl7hQ384FqP4T3DbNpXU8pt681l3UWCip1WUiD5JrkImUwCB9a7f2cq4CUTmi5r/xIMRPY1Q==", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", @@ -2252,33 +2252,33 @@ } }, "node_modules/@restorecommerce/acs-client": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@restorecommerce/acs-client/-/acs-client-1.4.15.tgz", - "integrity": "sha512-hCzT/WH/uxnyjF6CeVWy5XWFZcz2nZiDxYtIHWNQ+ANlc5AHn7zWrXmuM/AfI7JGIw6Y70/mOUiJhNTf4owSiA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@restorecommerce/acs-client/-/acs-client-1.5.1.tgz", + "integrity": "sha512-qQcyHHr/uVPjWUDls02bTRgTekNgXqzHzApIC8SqdCVemFmQjnkUsCMiTe9Bz8x9s1t0nNdMouva2yVTBs3j1g==", "dependencies": { - "@restorecommerce/grpc-client": "^2.2.0", - "@restorecommerce/kafka-client": "^1.1.23", + "@restorecommerce/grpc-client": "^2.2.1", + "@restorecommerce/kafka-client": "^1.2.1", "@restorecommerce/logger": "^1.2.10", - "@restorecommerce/rc-grpc-clients": "^5.1.22", + "@restorecommerce/rc-grpc-clients": "^5.1.23", "@restorecommerce/service-config": "^1.0.12", "lodash": "^4.17.21", "nconf": "^0.12.1", "node-eval": "^2.0.0", "redis": "^4.6.13", - "winston": "^3.11.0" + "winston": "^3.13.0" } }, "node_modules/@restorecommerce/chassis-srv": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/@restorecommerce/chassis-srv/-/chassis-srv-1.4.9.tgz", - "integrity": "sha512-LqA+oHf+8OqxVcHdibSCdcEEu7XugDPWsyeHD4MKHwjypaG++T9mRwQ6cclODjN/XsAKzBMC16bZmTENYCcuuw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@restorecommerce/chassis-srv/-/chassis-srv-1.5.0.tgz", + "integrity": "sha512-oODzFgwya6Fuwmbijojk6QO+3jUzRKHaMF6w1t3v8pyAbiUAEuBdWHcAjszIkG7YHi82LXcBYA2DSdPH2KFjvw==", "dependencies": { - "@grpc/grpc-js": "^1.10.1", - "@restorecommerce/grpc-client": "^2.2.0", - "@restorecommerce/kafka-client": "^1.1.22", + "@grpc/grpc-js": "^1.10.6", + "@restorecommerce/grpc-client": "^2.2.1", + "@restorecommerce/kafka-client": "^1.2.1", "@restorecommerce/logger": "^1.2.10", - "@restorecommerce/protos": "^6.8.0", - "@restorecommerce/rc-grpc-clients": "^5.1.22", + "@restorecommerce/protos": "^6.8.1", + "@restorecommerce/rc-grpc-clients": "^5.1.23", "@restorecommerce/service-config": "^1.0.12", "arangojs": "^8.7.0", "async": "^3.2.5", @@ -2291,13 +2291,13 @@ "lodash": "^4.17.21", "long": "^5.2.3", "nedb": "^1.8.0", - "nice-grpc": "^2.1.7", - "nice-grpc-server-reflection": "^2.0.9", + "nice-grpc": "^2.1.8", + "nice-grpc-server-reflection": "^2.0.10", "protobufjs": "^7.2.6", "redis": "^4.6.13" }, "engines": { - "node": ">= 18.0.0" + "node": ">= 20.0.0" } }, "node_modules/@restorecommerce/dev": { @@ -2547,41 +2547,41 @@ } }, "node_modules/@restorecommerce/grpc-client": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@restorecommerce/grpc-client/-/grpc-client-2.2.0.tgz", - "integrity": "sha512-Cr0nyly780WJttfpGfpJFBaKmis1EiY6/V9mwEbMgj9hV50IhHqluJOEQQ4OFurlYCzHkyw3+Yt/ToD6pySRgg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@restorecommerce/grpc-client/-/grpc-client-2.2.1.tgz", + "integrity": "sha512-pf9u0sJ5OiAsIG0xz+/Uqvgis6ZJ2gUxGsoO+Nbvp56tDM/ajXzPmNswdACLveLiaFPjW/nLoBCcmLBBFsHf+A==", "dependencies": { - "@grpc/grpc-js": "^1.9.11", - "@grpc/proto-loader": "^0.7.10", + "@grpc/grpc-js": "^1.10.6", + "@grpc/proto-loader": "^0.7.12", "@restorecommerce/logger": "^1.2.10", "cls-rtracer": "^2.6.3", "lodash": "^4.17.21", - "nice-grpc": "^2.1.7", - "nice-grpc-client-middleware-deadline": "^2.0.10", + "nice-grpc": "^2.1.8", + "nice-grpc-client-middleware-deadline": "^2.0.11", "nice-grpc-client-middleware-retry": "^3.1.7", "protobufjs": "^7.2.6", "retry": "^0.13.1", "rxjs": "^7.8.1", "uuid": "^9.0.1", - "winston": "^3.11.0" + "winston": "^3.13.0" }, "engines": { - "node": ">= 12.18.0" + "node": ">= 20.0.0" } }, "node_modules/@restorecommerce/kafka-client": { - "version": "1.1.23", - "resolved": "https://registry.npmjs.org/@restorecommerce/kafka-client/-/kafka-client-1.1.23.tgz", - "integrity": "sha512-ikhzHS21PeP39819nvDorNSo1txSL6dk56My/YYZxU0Bd9qEF44RK9+ViHGwlKrC1ATfcPJnHHA9G9Dp9wO8Ww==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@restorecommerce/kafka-client/-/kafka-client-1.2.1.tgz", + "integrity": "sha512-BQ7g55hro9hYq3PtTQYdnPzLg7+eW9MiosEUITH2/VjAz/cgWnzLzhavsw283lbsCh/iLgTK//MEe35fvzGF2w==", "dependencies": { "@restorecommerce/logger": "^1.2.10", - "@restorecommerce/rc-grpc-clients": "^5.1.22", + "@restorecommerce/rc-grpc-clients": "^5.1.23", "async": "^3.2.5", "cls-rtracer": "^2.6.3", "events": "^3.3.0", "kafkajs": "^2.2.4", "lodash": "^4.17.21", - "protobufjs": "^7.2.5", + "protobufjs": "^7.2.6", "retry": "^0.13.1", "winston": "^3.11.0" }, @@ -2606,17 +2606,17 @@ } }, "node_modules/@restorecommerce/protos": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@restorecommerce/protos/-/protos-6.8.0.tgz", - "integrity": "sha512-1pbXosFy6LXry2AKKyQyFgoDhYbfKzTtEtn++/SRxINK3OxDJStA2xoTKS9WPHKJKjGMv4jhauhp6U+poW7lzA==" + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@restorecommerce/protos/-/protos-6.8.1.tgz", + "integrity": "sha512-xkyC2IicFVLOmZzKtrDsuVw9M1Qq/1MN5V0IoiTbTlW17jlr8GgY3wlslDhRNR4grp6RThOZLBMWg+SxKdGoBw==" }, "node_modules/@restorecommerce/rc-grpc-clients": { - "version": "5.1.22", - "resolved": "https://registry.npmjs.org/@restorecommerce/rc-grpc-clients/-/rc-grpc-clients-5.1.22.tgz", - "integrity": "sha512-4cz2d73t93fVXl3z0Z88niq/0wcc03kVYS2dop+Uf4fRN3NKpXg4SOo8IRDxtW5yxnL2ooUWTR81kNEGg/7IHA==", + "version": "5.1.23", + "resolved": "https://registry.npmjs.org/@restorecommerce/rc-grpc-clients/-/rc-grpc-clients-5.1.23.tgz", + "integrity": "sha512-n6bLx55PP86MIa6obzbNvfs1cRUNwu42zAyMNPCIZ+KkO0sYgK2WmQfdB/uhKRCMDOkMM3fCYDVo8yzQw9Kgrg==", "dependencies": { "@grpc/grpc-js": "^1.9.11", - "@restorecommerce/grpc-client": "^2.2.0", + "@restorecommerce/grpc-client": "^2.2.1", "@types/google-protobuf": "^3.15.10", "google-protobuf": "^3.21.2", "nice-grpc": "^2.1.7", @@ -2630,14 +2630,14 @@ } }, "node_modules/@restorecommerce/resource-base-interface": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/@restorecommerce/resource-base-interface/-/resource-base-interface-1.4.8.tgz", - "integrity": "sha512-Wf1sF9zpwMSP/LooAqTgt+vM7mdbFc+Yq4t3DvHNc9DCbBRNXz9eHHNnOHwctLZn8p6igakeNvCaSreKVxsj7w==", - "dependencies": { - "@restorecommerce/chassis-srv": "^1.4.9", - "@restorecommerce/grpc-client": "^2.2.0", - "@restorecommerce/kafka-client": "^1.1.22", - "@restorecommerce/rc-grpc-clients": "^5.1.22", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@restorecommerce/resource-base-interface/-/resource-base-interface-1.5.0.tgz", + "integrity": "sha512-MMpcRNhNKz6cYEp8x0jPv6dK2reOKQka2Um/2za/o6c4OIHuG/1OwVija2uCzuDYtJT7Xzfgb4CQyYT6BomTmw==", + "dependencies": { + "@restorecommerce/chassis-srv": "^1.5.0", + "@restorecommerce/grpc-client": "^2.2.1", + "@restorecommerce/kafka-client": "^1.2.1", + "@restorecommerce/rc-grpc-clients": "^5.1.23", "@restorecommerce/service-config": "^1.0.12", "lodash": "^4.17.21", "redis": "^4.6.13" @@ -3354,9 +3354,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.29.tgz", - "integrity": "sha512-P99thMkD/1YkCvAtOd6/zGedKNA0p2fj4ZpjCzcNiSCBWgm3cNRTBfa/qjFnsKkkojxu4vVLtWpesnZ9+ap+gA==", + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "dependencies": { "undici-types": "~5.26.4" } @@ -3375,9 +3375,9 @@ "peer": true }, "node_modules/@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/triple-beam": { @@ -3406,22 +3406,22 @@ "integrity": "sha512-LKzNTjj+2j09wAo/vvVjzgw5qckJJzhdGgWHW7j69QIGdq/KnZrMAMIHQiWGl3Ccflh5/CudBAntTPYdprPltA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.3.1.tgz", - "integrity": "sha512-STEDMVQGww5lhCuNXVSQfbfuNII5E08QWkvAw5Qwf+bj2WT+JkG1uc+5/vXA3AOYMDHVOSpL+9rcbEUiHIm2dw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz", + "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.3.1", - "@typescript-eslint/type-utils": "7.3.1", - "@typescript-eslint/utils": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/type-utils": "7.7.0", + "@typescript-eslint/utils": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3462,13 +3462,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.3.1.tgz", - "integrity": "sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3479,9 +3479,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.3.1.tgz", - "integrity": "sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3492,19 +3492,19 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.3.1.tgz", - "integrity": "sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3520,18 +3520,18 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.3.1.tgz", - "integrity": "sha512-jIERm/6bYQ9HkynYlNZvXpzmXWZGhMbrOvq3jJzOSOlKXsVjrrolzWBjDW6/TvT5Q3WqaN4EkmcfdQwi9tDjBQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", + "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.3.1", - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/typescript-estree": "7.3.1", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "semver": "^7.6.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3545,13 +3545,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.3.1.tgz", - "integrity": "sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3561,16 +3561,31 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.3.1.tgz", - "integrity": "sha512-Rq49+pq7viTRCH48XAbTA+wdLRrB/3sRq4Lpk0oGDm0VmnjBrAOVXH/Laalmwsv2VpekiEfVFwJYVk6/e8uvQw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz", + "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.3.1", - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/typescript-estree": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4" }, "engines": { @@ -3590,13 +3605,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.3.1.tgz", - "integrity": "sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3607,9 +3622,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.3.1.tgz", - "integrity": "sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3620,19 +3635,19 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.3.1.tgz", - "integrity": "sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3648,13 +3663,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.3.1.tgz", - "integrity": "sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3664,6 +3679,21 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", @@ -3682,15 +3712,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.3.1.tgz", - "integrity": "sha512-iFhaysxFsMDQlzJn+vr3OrxN8NmdQkHks4WaqD4QBnt5hsq234wcYdyQ9uquzJJIDAj5W4wQne3yEsYA6OmXGw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz", + "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.3.1", - "@typescript-eslint/utils": "7.3.1", + "@typescript-eslint/typescript-estree": "7.7.0", + "@typescript-eslint/utils": "7.7.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3709,13 +3739,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.3.1.tgz", - "integrity": "sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3726,9 +3756,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.3.1.tgz", - "integrity": "sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3739,19 +3769,19 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.3.1.tgz", - "integrity": "sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/visitor-keys": "7.3.1", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3767,18 +3797,18 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.3.1.tgz", - "integrity": "sha512-jIERm/6bYQ9HkynYlNZvXpzmXWZGhMbrOvq3jJzOSOlKXsVjrrolzWBjDW6/TvT5Q3WqaN4EkmcfdQwi9tDjBQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", + "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.3.1", - "@typescript-eslint/types": "7.3.1", - "@typescript-eslint/typescript-estree": "7.3.1", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "semver": "^7.6.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3792,13 +3822,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.3.1.tgz", - "integrity": "sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.3.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3808,6 +3838,21 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/types": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", @@ -4275,7 +4320,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -4306,7 +4350,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "devOptional": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -4450,7 +4493,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "devOptional": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -4707,7 +4749,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "devOptional": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -5815,6 +5856,54 @@ "node": ">=0.10" } }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -5933,7 +6022,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "devOptional": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -5950,7 +6038,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "devOptional": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -6407,18 +6494,21 @@ } }, "node_modules/es-abstract": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", - "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==", - "devOptional": true, + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.6", + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.2", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", @@ -6426,15 +6516,16 @@ "globalthis": "^1.0.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.1", + "hasown": "^2.0.2", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", @@ -6442,17 +6533,17 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.0", + "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.1", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -6465,7 +6556,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "devOptional": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -6477,7 +6567,17 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "devOptional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dependencies": { + "es-errors": "^1.3.0" + }, "engines": { "node": ">= 0.4" } @@ -6486,7 +6586,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "devOptional": true, "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -6500,7 +6599,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "devOptional": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -7202,7 +7300,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "devOptional": true, "dependencies": { "is-callable": "^1.1.3" } @@ -7363,7 +7460,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "devOptional": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7372,7 +7468,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7390,7 +7485,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "devOptional": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7415,7 +7509,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "devOptional": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -7446,7 +7539,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -7704,7 +7796,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "devOptional": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -7744,7 +7835,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "devOptional": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -7851,7 +7941,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "devOptional": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7869,7 +7958,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "devOptional": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -7881,7 +7969,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -7893,7 +7980,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -7905,7 +7991,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "devOptional": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -7917,10 +8002,9 @@ } }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "devOptional": true, + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, @@ -8274,7 +8358,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "devOptional": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -8305,7 +8388,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -8327,7 +8409,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "devOptional": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -8351,7 +8432,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -8382,7 +8462,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -8402,11 +8481,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "devOptional": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8495,7 +8587,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -8522,7 +8613,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "devOptional": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8584,7 +8674,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -8600,7 +8689,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.7" }, @@ -8626,7 +8714,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "devOptional": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8641,7 +8728,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "devOptional": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -8668,7 +8754,6 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "devOptional": true, "dependencies": { "which-typed-array": "^1.1.14" }, @@ -8707,7 +8792,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -8727,8 +8811,7 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "devOptional": true + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/isexe": { "version": "2.0.0", @@ -9579,9 +9662,9 @@ } }, "node_modules/mocha": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", - "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -9848,19 +9931,19 @@ "optional": true }, "node_modules/nice-grpc": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/nice-grpc/-/nice-grpc-2.1.7.tgz", - "integrity": "sha512-pSaZk5Y3PHGAPObOSXTrANgimA6T//szxlcKOnnyttpYwO0gyOpX2WsaFK4fbGJizPVxXjwqrXpPOSHMwM2vlg==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/nice-grpc/-/nice-grpc-2.1.8.tgz", + "integrity": "sha512-pTugD3cZ1Vb0Q2OjZZh80wpLY6L7jSADnzY7Dq6mL9EGUJJF5mfQjcHF4gqpQtyTq2YsZgPIArfNcq0k3ApgQg==", "dependencies": { - "@grpc/grpc-js": "^1.9.5", + "@grpc/grpc-js": "~1.9.14", "abort-controller-x": "^0.4.0", "nice-grpc-common": "^2.0.2" } }, "node_modules/nice-grpc-client-middleware-deadline": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/nice-grpc-client-middleware-deadline/-/nice-grpc-client-middleware-deadline-2.0.10.tgz", - "integrity": "sha512-9ja17LrW5kzqzhbU2NUddqB7OFWHaT2cEi0e+0xbArtE/A4EhEe0Ei0/8xb1eflNPgdguK9+sB16e+beCDvrbg==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/nice-grpc-client-middleware-deadline/-/nice-grpc-client-middleware-deadline-2.0.11.tgz", + "integrity": "sha512-mwO70/ye7EhbW13HXx3Hjq05QBKR52qyxYzOwBVQvZS/THyT0h5fGbtmQBtlHxAA+lyVJdt51PXu6ic5al/eeg==", "dependencies": { "nice-grpc-common": "^2.0.2" } @@ -9883,14 +9966,14 @@ } }, "node_modules/nice-grpc-server-reflection": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/nice-grpc-server-reflection/-/nice-grpc-server-reflection-2.0.9.tgz", - "integrity": "sha512-Q15zy2+va4KjJbAro+IGL6zcJuXs1nlJNzXtYY2aoYprOVSLQhhtL7z/YymAkb9nWoLF9gZg0o1B/GXc31fD3A==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/nice-grpc-server-reflection/-/nice-grpc-server-reflection-2.0.10.tgz", + "integrity": "sha512-VCOwGViuYJg7XND9gFVxfWWQ9CYnR0KzDIzDmVEytyWYEMkAstMRbRmOyfU3WlV2wC8dk5aCid0BFtgSvxucVw==", "dependencies": { - "@grpc/grpc-js": "^1.9.5", + "@grpc/grpc-js": "~1.9.14", "@types/google-protobuf": "^3.7.4", "google-protobuf": "^3.15.6", - "nice-grpc": "^2.1.7" + "nice-grpc": "^2.1.8" } }, "node_modules/nice-try": { @@ -13094,7 +13177,6 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "devOptional": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13103,7 +13185,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "devOptional": true, "engines": { "node": ">= 0.4" } @@ -13112,7 +13193,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -13648,7 +13728,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "devOptional": true, "engines": { "node": ">= 0.4" } @@ -14091,7 +14170,6 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -14380,13 +14458,12 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/safe-array-concat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", - "devOptional": true, + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -14429,7 +14506,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -18832,7 +18908,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", - "devOptional": true, "dependencies": { "define-data-property": "^1.1.2", "es-errors": "^1.3.0", @@ -18849,7 +18924,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "devOptional": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -18959,7 +19033,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -19396,14 +19469,14 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "devOptional": true, + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -19413,28 +19486,29 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", - "devOptional": true, + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "devOptional": true, + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19809,9 +19883,14 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/traverse": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", - "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz", + "integrity": "sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==", + "dependencies": { + "gopd": "^1.0.1", + "typedarray.prototype.slice": "^1.0.3", + "which-typed-array": "^1.1.15" + }, "engines": { "node": ">= 0.4" }, @@ -19838,9 +19917,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", - "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { "node": ">=16" @@ -20179,7 +20258,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -20193,7 +20271,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -20212,7 +20289,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "devOptional": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -20229,10 +20305,9 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", - "devOptional": true, + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -20248,10 +20323,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedarray.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.3.tgz", + "integrity": "sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-errors": "^1.3.0", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-offset": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -20279,7 +20373,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "devOptional": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -20513,7 +20606,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "devOptional": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -20526,16 +20618,15 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", - "devOptional": true, + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dependencies": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -20545,9 +20636,9 @@ } }, "node_modules/winston": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.12.0.tgz", - "integrity": "sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", + "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", diff --git a/package.json b/package.json index ecca67a..b51090a 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,13 @@ ], "type": "module", "dependencies": { - "@restorecommerce/acs-client": "^1.4.15", - "@restorecommerce/chassis-srv": "^1.4.9", - "@restorecommerce/grpc-client": "^2.2.0", - "@restorecommerce/kafka-client": "^1.1.23", + "@restorecommerce/acs-client": "^1.5.1", + "@restorecommerce/chassis-srv": "^1.5.0", + "@restorecommerce/grpc-client": "^2.2.1", + "@restorecommerce/kafka-client": "^1.2.1", "@restorecommerce/logger": "^1.2.10", - "@restorecommerce/rc-grpc-clients": "^5.1.22", - "@restorecommerce/resource-base-interface": "^1.4.8", + "@restorecommerce/rc-grpc-clients": "^5.1.23", + "@restorecommerce/resource-base-interface": "^1.5.0", "@restorecommerce/service-config": "^1.0.12", "apollo-boost": "^0.4.9", "apollo-cache-inmemory": "^1.6.6", @@ -35,23 +35,23 @@ "js-yaml": "^4.1.0", "lodash-es": "^4.17.21", "node-eval": "^2.0.0", - "traverse": "^0.6.8" + "traverse": "^0.6.9" }, "devDependencies": { - "@alenon/grpc-mock-server": "^3.1.9", - "@commitlint/cli": "^19.2.1", - "@commitlint/config-conventional": "^19.1.0", - "@grpc/proto-loader": "^0.7.10", + "@alenon/grpc-mock-server": "^3.1.10", + "@commitlint/cli": "^19.2.2", + "@commitlint/config-conventional": "^19.2.2", + "@grpc/proto-loader": "^0.7.12", "@restorecommerce/dev": "^0.0.9", - "@restorecommerce/protos": "^6.8.0", + "@restorecommerce/protos": "^6.8.1", "@semantic-release-plus/docker": "^3.1.3", "@types/lodash-es": "^4.17.12", "@types/mocha": "^10.0.6", "@types/nock": "^11.1.0", - "@types/node": "^20.11.29", - "@typescript-eslint/eslint-plugin": "^7.3.1", + "@types/node": "^20.12.7", + "@typescript-eslint/eslint-plugin": "^7.7.0", "@typescript-eslint/eslint-plugin-tslint": "^7.0.2", - "@typescript-eslint/parser": "^7.3.1", + "@typescript-eslint/parser": "^7.7.0", "c8": "^9.1.0", "coveralls": "^3.1.1", "cross-env": "^7.0.3", @@ -60,7 +60,7 @@ "eslint": "^8.57.0", "eslint-plugin-prefer-arrow-functions": "^3.3.2", "husky": "^9.0.11", - "mocha": "^10.3.0", + "mocha": "^10.4.0", "nock": "^13.5.4", "nodemon": "^3.1.0", "npm-run-all": "^4.1.5", @@ -68,7 +68,7 @@ "should": "^13.2.3", "ts-node": "^10.9.2", "tslint": "^6.1.3", - "typescript": "^5.4.2" + "typescript": "^5.4.5" }, "overrides": { "@grpc/grpc-js": "1.10.1"