diff --git a/Methodology Library/CDM/CDM AMS-II.G/readMe.md b/Methodology Library/CDM/CDM AMS-II.G/readMe.md index 558179b228..d99753b77b 100644 --- a/Methodology Library/CDM/CDM AMS-II.G/readMe.md +++ b/Methodology Library/CDM/CDM AMS-II.G/readMe.md @@ -36,7 +36,7 @@ AMS-II.G provides a standardized and measurable framework for clean cooking proj ## Demo Video -Coming Soon +[Youtube](https://www.youtube.com/watch?v=jfl72_fL6iU) ## Policy Workflow @@ -46,7 +46,7 @@ Coming Soon This policy is published to Hedera network and can either be imported via Github (.policy file) or IPSF timestamp. -Policy: 1690817087.866705082 +Policy: 1695225791.622644989 Tool 30: 1690820465.670044734 Tool 33: 1690820484.707441003 @@ -74,7 +74,7 @@ Certified Emission Reduction (CER) credits, each equivalent to one tonne of CO2. ### Step By Step -1. The policy can be imported using IPFS timestamp 1690462366.484472937 +1. The policy can be imported using IPFS timestamp 1695225791.622644989 image diff --git a/Methodology Library/CDM/CDM AMS-III.AR/readme.md b/Methodology Library/CDM/CDM AMS-III.AR/readme.md index 3171cfed15..da19fe6b7b 100644 --- a/Methodology Library/CDM/CDM AMS-III.AR/readme.md +++ b/Methodology Library/CDM/CDM AMS-III.AR/readme.md @@ -51,7 +51,7 @@ reductions. This policy is published to the Hedera network and can either be imported via Github(.policy file) or IPFS timestamp. Timestamp: -Policy: 1690817347.617246606 +Policy: 1695233862.252855821 Tool 33: 1690820529.197570717 ### Available Roles @@ -93,7 +93,7 @@ Certified Emission Reduction (CER) credits, each equivalent to one tonne of CO2. ### Step By Step -1. The policy can be imported using IPFS timestamp 1688046287.912072347 +1. The policy can be imported using IPFS timestamp 1695233862.252855821 image diff --git a/Methodology Library/CDM/CDM AMS-III.D/readme.md b/Methodology Library/CDM/CDM AMS-III.D/readme.md index 39a7cd2d46..ce2c3e1ff5 100644 --- a/Methodology Library/CDM/CDM AMS-III.D/readme.md +++ b/Methodology Library/CDM/CDM AMS-III.D/readme.md @@ -34,7 +34,7 @@ In the context of modern emission reduction projects, the necessity for transpar ## Demo Video -Coming Soon +[Youtube](https://www.youtube.com/watch?v=jWpCgWl-92E&t=7s) ## Policy Workflow @@ -45,7 +45,7 @@ Coming Soon This policy is published to Hedera network and can either be imported via Github (.policy file) or IPSF timestamp. -Policy: 1693223777.317635003 +Policy: 1695235455.560040612 ### Available Roles @@ -78,7 +78,7 @@ Certified Emission Reduction (CER) credits, each equivalent to one tonne of CO2. ### Step By Step -1. The policy can be imported using IPFS timestamp 1693223777.317635003 +1. The policy can be imported using IPFS timestamp 1695235455.560040612 image diff --git a/Methodology Library/CDM/CDM AR-ACM0003/readme.md b/Methodology Library/CDM/CDM AR-ACM0003/readme.md index d991677994..9c9e68fbde 100644 --- a/Methodology Library/CDM/CDM AR-ACM0003/readme.md +++ b/Methodology Library/CDM/CDM AR-ACM0003/readme.md @@ -19,5 +19,5 @@ For Demo purpose, we have uploaded CDM Policy into IPFS and created Timestamps, | Version | IPFS Timestamp | Policy File Link | Version Differences | |---|---|---|---:| -| CDM AR-ACM0003 | 1690817784.010153219 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/CDM/CDM.policy) | CDM AR-ACM0003 Methodology | +| CDM AR-ACM0003 | 1695237303.012398003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/CDM/CDM.policy) | CDM AR-ACM0003 Methodology | diff --git a/Methodology Library/GoldStandard/GoldStandard AR/README.md b/Methodology Library/GoldStandard/GoldStandard AR/README.md index e53ac8da6e..cd264ed185 100644 --- a/Methodology Library/GoldStandard/GoldStandard AR/README.md +++ b/Methodology Library/GoldStandard/GoldStandard AR/README.md @@ -20,4 +20,4 @@ The Gold Standard AR methodology promotes sustainable land use practices that co | Version | IPFS Timestamp | Policy File Link | Version Differences | |---|---|---|---:| -| GoldStandard AR | 1690818470.019357927 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/GoldStandard/GoldStandard%20AR/Gold%20Standard%20AR.policy) | GoldStandard AR | +| GoldStandard AR | 1695251826.459491276 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/GoldStandard/GoldStandard%20AR/Gold%20Standard%20AR.policy) | GoldStandard AR | diff --git a/Methodology Library/Verra/Verra Redd/VM0007/Policies/Verra VM0007 (1.0.0).policy b/Methodology Library/Verra/Verra Redd/VM0007/Policies/Verra VM0007 (1.0.0).policy index 2f418e83e9..8ee9441cf3 100644 Binary files a/Methodology Library/Verra/Verra Redd/VM0007/Policies/Verra VM0007 (1.0.0).policy and b/Methodology Library/Verra/Verra Redd/VM0007/Policies/Verra VM0007 (1.0.0).policy differ diff --git a/Methodology Library/Verra/Verra Redd/VM0007/readme.md b/Methodology Library/Verra/Verra Redd/VM0007/readme.md index 87d0de556a..33dea27af5 100644 --- a/Methodology Library/Verra/Verra Redd/VM0007/readme.md +++ b/Methodology Library/Verra/Verra Redd/VM0007/readme.md @@ -26,9 +26,9 @@ For Demo purpose, we have uploaded two versions of Verra Policies into IPFS and | Version | IPFS Timestamp | Policy File Link | Version Differences | |---|---|---|---:| -| Verra 1.1.0 | 1690818971.712442003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0007/Policies/Verra%20REDD.policy) | Verra Methodology | -| Verra 2.2.2 | 1690819138.885132174 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0007/Policies/Verra%20REDD%20Policy%202.policy) | Verra 1.1.0 + revoke actions | -| Verra REDD Policy 3 groups | 1690819293.839911342 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0007/Policies/Verra%20REDD%20Policy%203%20groups%20(1663846582.307635866).policy) | Demonstrates the usage of private groups, which accept members by invitation, and multi-signature approvals. The VVB role has been changed, in this new version it is an 'organisation' groupping multiple individual identities/users. When a project proponent selects a VVB it is no longer represented by a single identity/user, but by an organisation where multiple individuals can approve the project. | +| Verra 1.1.0 | 1695249211.391769223 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0007/Policies/Verra%20REDD.policy) | Verra Methodology | +| Verra 2.2.2 | 1695248454.852259003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0007/Policies/Verra%20REDD%20Policy%202.policy) | Verra 1.1.0 + revoke actions | +| Verra REDD Policy 3 groups | 1695248864.688529003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0007/Policies/Verra%20REDD%20Policy%203%20groups%20(1663846582.307635866).policy) | Demonstrates the usage of private groups, which accept members by invitation, and multi-signature approvals. The VVB role has been changed, in this new version it is an 'organisation' groupping multiple individual identities/users. When a project proponent selects a VVB it is no longer represented by a single identity/user, but by an organisation where multiple individuals can approve the project. | In addition to the above Policy Versions, we have also added Schema Design Template file for demo purpose. Please check : [Sample Design Template](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0007/REDD%20APD%20Schema%20Design%20Template.xlsx) diff --git a/Methodology Library/Verra/Verra Redd/VM0017/README.md b/Methodology Library/Verra/Verra Redd/VM0017/README.md index 2384415b16..70c375c116 100644 --- a/Methodology Library/Verra/Verra Redd/VM0017/README.md +++ b/Methodology Library/Verra/Verra Redd/VM0017/README.md @@ -26,4 +26,4 @@ For Demo purpose, we have uploaded Verra Policies into IPFS and created Timestam | Version | IPFS Timestamp | Policy File Link | Version Differences | |---|---|---|---:| -| Verra Redd 4 | 1690819670.554961003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0017/Policies/Verra%20REDD%20Policy%204.policy) | Verra Methodology | +| Verra Redd 4 | 1695250025.604149003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0017/Policies/Verra%20REDD%20Policy%204.policy) | Verra Methodology | diff --git a/Methodology Library/Verra/Verra Redd/VM0042/readMe.md b/Methodology Library/Verra/Verra Redd/VM0042/readMe.md index 7138b000fe..dc2ec64846 100644 --- a/Methodology Library/Verra/Verra Redd/VM0042/readMe.md +++ b/Methodology Library/Verra/Verra Redd/VM0042/readMe.md @@ -24,4 +24,4 @@ For Demo purpose, we have uploaded Verra Policies into IPFS and created Timestam | Version | IPFS Timestamp | Policy File Link | Version Differences | |---|---|---|---:| -| Verra Redd 5 | 1690820413.911697512 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0042/Policies/Verra%20REDD%20Policy%205.policy) | Verra Methodology | +| Verra Redd 5 | 1695251173.300475003 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VM0042/Policies/Verra%20REDD%20Policy%205.policy) | Verra Methodology | diff --git a/Methodology Library/Verra/Verra Redd/VerraARR/README.md b/Methodology Library/Verra/Verra Redd/VerraARR/README.md index 53b4a5ecc0..b70a192b77 100644 --- a/Methodology Library/Verra/Verra Redd/VerraARR/README.md +++ b/Methodology Library/Verra/Verra Redd/VerraARR/README.md @@ -21,4 +21,4 @@ Roles in the below Workflow Diagram are represented as follows : Project Propone | Version | IPFS Timestamp | Policy File Link | Version Differences | |---|---|---|---:| -| VerraARR | 1690818786.894085490 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VerraARR/VerraARR.policy) | Verra ARR | +| VerraARR | 1695247491.606164733 | [Link](https://github.com/hashgraph/guardian/blob/main/Methodology%20Library/Verra/Verra%20Redd/VerraARR/VerraARR.policy) | Verra ARR | diff --git a/analytics-service/package.json b/analytics-service/package.json index dce4651cfe..6a2be62053 100644 --- a/analytics-service/package.json +++ b/analytics-service/package.json @@ -9,8 +9,8 @@ }, "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", + "@guardian/interfaces": "^2.17.0", "@nestjs/common": "^9.4.1", "@nestjs/core": "^9.4.1", "@nestjs/jwt": "^10.0.3", @@ -76,6 +76,5 @@ "start": "node dist/index.js", "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ui-service.xml" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/api-gateway/package.json b/api-gateway/package.json index 404b26a339..3d7584ffb5 100644 --- a/api-gateway/package.json +++ b/api-gateway/package.json @@ -8,8 +8,8 @@ }, "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", + "@guardian/interfaces": "^2.17.0", "@nestjs/common": "^9.4.1", "@nestjs/core": "^9.4.1", "@nestjs/jwt": "^10.0.3", @@ -77,6 +77,5 @@ "start": "node dist/index.js", "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ui-service.xml" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/api-gateway/src/api/service/analytics.ts b/api-gateway/src/api/service/analytics.ts index 87378bc13d..a8c48610bb 100644 --- a/api-gateway/src/api/service/analytics.ts +++ b/api-gateway/src/api/service/analytics.ts @@ -1,13 +1,71 @@ import { Guardians } from '@helpers/guardians'; import { Body, Controller, HttpCode, HttpException, HttpStatus, Post, Req } from '@nestjs/common'; -import { ApiTags } from '@nestjs/swagger'; +import { + ApiInternalServerErrorResponse, + ApiUnauthorizedResponse, + ApiForbiddenResponse, + ApiBody, + ApiOkResponse, + ApiOperation, + ApiSecurity, + ApiTags +} from '@nestjs/swagger'; import { checkPermission } from '@auth/authorization-helper'; import { UserRole } from '@guardian/interfaces'; +import { + FilterDocumentsDTO, + FilterModulesDTO, + FilterPoliciesDTO, + FilterSchemasDTO, + FilterSearchPoliciesDTO, + InternalServerErrorDTO, + CompareDocumentsDTO, + CompareModulesDTO, + ComparePoliciesDTO, + CompareSchemasDTO, + SearchPoliciesDTO +} from '@middlewares/validation/schemas'; + +const ONLY_SR = ' Only users with the Standard Registry role are allowed to make the request.' @Controller('analytics') @ApiTags('analytics') export class AnalyticsApi { + /** + * Search policies + */ @Post('/search/policies') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Search policies.', + description: 'Search policies.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterSearchPoliciesDTO, + examples: { + Filter: { + value: { + policyId: '000000000000000000000000' + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: SearchPoliciesDTO, + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async searchPolicies(@Body() body, @Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -30,7 +88,55 @@ export class AnalyticsApi { } } + /** + * Compare policies + */ @Post('/compare/policies') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare policies.', + description: 'Compare policies.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterPoliciesDTO, + examples: { + Filter1: { + value: { + policyId1: '000000000000000000000001', + policyId2: '000000000000000000000002', + eventsLvl: '0', + propLvl: '0', + childrenLvl: '0', + idLvl: '0' + } + }, + Filter2: { + value: { + policyIds: ['000000000000000000000001', '000000000000000000000002'], + eventsLvl: '0', + propLvl: '0', + childrenLvl: '0', + idLvl: '0' + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: ComparePoliciesDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async comparePolicies(@Body() body, @Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -72,7 +178,45 @@ export class AnalyticsApi { } } + /** + * Compare modules + */ @Post('/compare/modules') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare modules.', + description: 'Compare modules.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterModulesDTO, + examples: { + Filter: { + value: { + moduleId1: '000000000000000000000001', + moduleId2: '000000000000000000000002', + propLvl: '0', + childrenLvl: '0', + idLvl: '0' + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: CompareModulesDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async compareModules(@Body() body, @Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -110,6 +254,39 @@ export class AnalyticsApi { * Compare schemas */ @Post('/compare/schemas') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare schemas.', + description: 'Compare schemas.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterSchemasDTO, + examples: { + Filter: { + value: { + schemaId1: '000000000000000000000001', + schemaId2: '000000000000000000000002', + idLvl: '0' + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: CompareSchemasDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async compareSchemas(@Body() body, @Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -135,6 +312,43 @@ export class AnalyticsApi { * Compare documents */ @Post('/compare/documents') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare documents.', + description: 'Compare documents.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterDocumentsDTO, + examples: { + Filter1: { + value: { + documentId1: '000000000000000000000001', + documentId2: '000000000000000000000002' + } + }, + Filter2: { + value: { + documentIds: ['000000000000000000000001', '000000000000000000000002'], + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: CompareDocumentsDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async compareDocuments(@Body() body, @Req() req): Promise { const guardians = new Guardians(); @@ -175,11 +389,54 @@ export class AnalyticsApi { } /** - * Compare policies export - * @param body - * @param req + * Compare policies (CSV) */ @Post('/compare/policies/export') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare policies.', + description: 'Compare policies.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterPoliciesDTO, + examples: { + Filter1: { + value: { + policyId1: '000000000000000000000001', + policyId2: '000000000000000000000002', + eventsLvl: '0', + propLvl: '0', + childrenLvl: '0', + idLvl: '0' + } + }, + Filter2: { + value: { + policyIds: ['000000000000000000000001', '000000000000000000000002'], + eventsLvl: '0', + propLvl: '0', + childrenLvl: '0', + idLvl: '0' + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: String + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async comparePoliciesExport(@Body() body, @Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -220,7 +477,45 @@ export class AnalyticsApi { } } + /** + * Compare modules (CSV) + */ @Post('/compare/modules/export') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare modules.', + description: 'Compare modules.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterModulesDTO, + examples: { + Filter: { + value: { + moduleId1: '000000000000000000000001', + moduleId2: '000000000000000000000002', + propLvl: '0', + childrenLvl: '0', + idLvl: '0' + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: String + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async compareModulesExport(@Body() body, @Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -256,11 +551,42 @@ export class AnalyticsApi { } /** - * compareSchemasExport - * @param body - * @param req + * Compare schemas (CSV) */ @Post('/compare/schemas/export') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare schemas.', + description: 'Compare schemas.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterSchemasDTO, + examples: { + Filter: { + value: { + schemaId1: '000000000000000000000001', + schemaId2: '000000000000000000000002', + idLvl: '0' + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: String + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async compareSchemasExport(@Body() body, @Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -284,11 +610,46 @@ export class AnalyticsApi { } /** - * Compare documents export - * @param body - * @param req + * Compare documents (CSV) */ @Post('/compare/documents/export') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Compare documents.', + description: 'Compare documents.' + ONLY_SR, + }) + @ApiBody({ + description: 'Filters.', + required: true, + type: FilterDocumentsDTO, + examples: { + Filter1: { + value: { + documentId1: '000000000000000000000001', + documentId2: '000000000000000000000002' + } + }, + Filter2: { + value: { + documentIds: ['000000000000000000000001', '000000000000000000000002'], + } + } + } + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: String + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async compareDocumentsExport(@Body() body, @Req() req): Promise { const guardians = new Guardians(); diff --git a/api-gateway/src/api/service/schema.ts b/api-gateway/src/api/service/schema.ts index 1fc8b0d098..8fcac4ba97 100644 --- a/api-gateway/src/api/service/schema.ts +++ b/api-gateway/src/api/service/schema.ts @@ -17,8 +17,8 @@ import { ApiOkResponse, ApiOperation, ApiSecurity, + ApiBody, ApiTags, - getSchemaPath, ApiExtraModels } from '@nestjs/swagger'; import { @@ -42,7 +42,15 @@ import { ServiceError } from '@helpers/service-requests-base'; import { SchemaUtils } from '@helpers/schema-utils'; import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator'; import { ApiImplicitParam } from '@nestjs/swagger/dist/decorators/api-implicit-param.decorator'; -import { InternalServerErrorDTO, TaskDTO, SystemSchemaDTO, SchemaDTO, ExportSchemaDTO } from '@middlewares/validation/schemas'; +import { + InternalServerErrorDTO, + TaskDTO, + SystemSchemaDTO, + SchemaDTO, + ExportSchemaDTO, + MessageSchemaDTO, + VersionSchemaDTO +} from '@middlewares/validation/schemas'; const ONLY_SR = ' Only users with the Standard Registry role are allowed to make the request.' @@ -189,9 +197,7 @@ export class SingleSchemaApi { @ApiOkResponse({ description: 'Successful operation.', isArray: true, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -201,9 +207,7 @@ export class SingleSchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) async getSchemaParents(@Req() req): Promise { await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER)(req.user); @@ -270,21 +274,21 @@ export class SchemaApi { type: String, description: 'Policy id', required: false, - example: '000000000000000000000000' + example: '000000000000000000000001' }) @ApiImplicitQuery({ name: 'moduleId', type: String, description: 'Module id', required: false, - example: '000000000000000000000000' + example: '000000000000000000000001' }) @ApiImplicitQuery({ name: 'toolId', type: String, description: 'Tool id', required: false, - example: '000000000000000000000000' + example: '000000000000000000000001' }) @ApiImplicitQuery({ name: 'topicId', @@ -304,9 +308,7 @@ export class SchemaApi { description: 'Total items in the collection.' } }, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -316,9 +318,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async getSchemasPage(@Req() req, @Response() res): Promise { @@ -384,9 +384,7 @@ export class SchemaApi { description: 'Total items in the collection.' } }, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -396,9 +394,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async getSchemasPageByTopicId(@Req() req, @Response() res): Promise { @@ -434,9 +430,7 @@ export class SchemaApi { }) @ApiOkResponse({ description: 'Successful operation.', - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -446,9 +440,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async getSchemaByType(@Req() req, @Response() res): Promise { @@ -493,9 +485,7 @@ export class SchemaApi { @ApiOkResponse({ description: 'Successful operation.', isArray: true, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -505,9 +495,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async getAll(@Req() req, @Response() res): Promise { @@ -542,12 +530,15 @@ export class SchemaApi { required: true, example: '0.0.1' }) + @ApiBody({ + description: 'Object that contains a valid schema.', + required: true, + type: SchemaDTO + }) @ApiOkResponse({ description: 'Successful operation.', isArray: true, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -557,9 +548,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) async createNewSchema(@Req() req, @Response() res): Promise { @@ -597,11 +586,14 @@ export class SchemaApi { required: true, example: '0.0.1' }) + @ApiBody({ + description: 'Object that contains a valid schema.', + required: true, + type: SchemaDTO + }) @ApiOkResponse({ description: 'Successful operation.', - schema: { - $ref: getSchemaPath(TaskDTO) - }, + type: TaskDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -611,9 +603,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) async createNewSchemaAsync(@Req() req, @Response() res): Promise { @@ -648,12 +638,15 @@ export class SchemaApi { summary: 'Updates the schema.', description: 'Updates the schema.' + ONLY_SR, }) + @ApiBody({ + description: 'Object that contains a valid schema.', + required: true, + type: SchemaDTO + }) @ApiOkResponse({ description: 'Successful operation.', isArray: true, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -663,9 +656,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async setSchema(@Req() req, @Response() res): Promise { @@ -708,14 +699,12 @@ export class SchemaApi { type: String, description: 'Schema ID', required: true, - example: '000000000000000000000000' + example: '000000000000000000000001' }) @ApiOkResponse({ description: 'Successful operation.', isArray: true, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -725,9 +714,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async deleteSchema(@Req() req, @Response() res): Promise { @@ -776,7 +763,19 @@ export class SchemaApi { type: String, description: 'Schema ID', required: true, - example: '000000000000000000000000' + example: '000000000000000000000001' + }) + @ApiBody({ + description: 'Object that contains version.', + required: true, + type: VersionSchemaDTO, + examples: { + Version: { + value: { + version: '1.0.0' + } + } + } }) @ApiOkResponse({ description: 'Successful operation.', @@ -789,9 +788,7 @@ export class SchemaApi { description: 'Total items in the collection.' } }, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -801,9 +798,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async publishSchema(@Req() req, @Response() res): Promise { @@ -812,8 +807,8 @@ export class SchemaApi { const guardians = new Guardians(); const schemaId = req.params.schemaId; const { version } = req.body; - let schema; - let allVersion; + let schema: ISchema; + let allVersion: ISchema[]; try { schema = await guardians.getSchemaById(schemaId); } catch (error) { @@ -867,13 +862,23 @@ export class SchemaApi { type: String, description: 'Schema ID', required: true, - example: '000000000000000000000000' + example: '000000000000000000000001' + }) + @ApiBody({ + description: 'Object that contains version.', + required: true, + type: VersionSchemaDTO, + examples: { + Version: { + value: { + version: '1.0.0' + } + } + } }) @ApiOkResponse({ description: 'Successful operation.', - schema: { - $ref: getSchemaPath(TaskDTO) - }, + type: TaskDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -883,9 +888,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) async publishSchemaAsync(@Req() req, @Response() res): Promise { @@ -932,6 +935,18 @@ export class SchemaApi { summary: 'Previews the schema from IPFS without loading it into the local DB.', description: 'Previews the schema from IPFS without loading it into the local DB.' + ONLY_SR, }) + @ApiBody({ + description: 'Object that contains version.', + required: true, + type: MessageSchemaDTO, + examples: { + Message: { + value: { + messageId: '0000000000.000000000' + } + } + } + }) @ApiOkResponse({ description: 'Successful operation.', schema: { @@ -946,9 +961,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async importFromMessagePreview(@Req() req, @Response() res): Promise { @@ -973,11 +986,21 @@ export class SchemaApi { summary: 'Previews the schema from IPFS without loading it into the local DB.', description: 'Previews the schema from IPFS without loading it into the local DB.' + ONLY_SR, }) + @ApiBody({ + description: 'Object that contains version.', + required: true, + type: MessageSchemaDTO, + examples: { + Message: { + value: { + messageId: '0000000000.000000000' + } + } + } + }) @ApiOkResponse({ description: 'Successful operation.', - schema: { - $ref: getSchemaPath(TaskDTO) - }, + type: TaskDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -987,9 +1010,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) async importFromMessagePreviewAsync(@Req() req, @Response() res): Promise { @@ -1021,6 +1042,10 @@ export class SchemaApi { summary: 'Previews the schema from a zip file.', description: 'Previews the schema from a zip file.' + ONLY_SR, }) + @ApiBody({ + description: 'A zip file containing schema to be imported.', + required: true + }) @ApiOkResponse({ description: 'Successful operation.', schema: { @@ -1035,9 +1060,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async importFromFilePreview(@Req() req, @Response() res): Promise { @@ -1073,6 +1096,18 @@ export class SchemaApi { required: true, example: '0.0.1' }) + @ApiBody({ + description: 'Object that contains version.', + required: true, + type: MessageSchemaDTO, + examples: { + Message: { + value: { + messageId: '0000000000.000000000' + } + } + } + }) @ApiOkResponse({ description: 'Successful operation.', isArray: true, @@ -1084,9 +1119,7 @@ export class SchemaApi { description: 'Total items in the collection.' } }, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -1096,9 +1129,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) async importFromMessage(@Req() req, @Response() res): Promise { @@ -1140,11 +1171,21 @@ export class SchemaApi { required: true, example: '0.0.1' }) + @ApiBody({ + description: 'Object that contains version.', + required: true, + type: MessageSchemaDTO, + examples: { + Message: { + value: { + messageId: '0000000000.000000000' + } + } + } + }) @ApiOkResponse({ description: 'Successful operation.', - schema: { - $ref: getSchemaPath(TaskDTO) - }, + type: TaskDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -1154,9 +1195,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) async importFromMessageAsync(@Req() req, @Response() res): Promise { @@ -1196,6 +1235,10 @@ export class SchemaApi { required: true, example: '0.0.1' }) + @ApiBody({ + description: 'A zip file containing schema to be imported.', + required: true + }) @ApiOkResponse({ description: 'Successful operation.', isArray: true, @@ -1207,9 +1250,7 @@ export class SchemaApi { description: 'Total items in the collection.' } }, - schema: { - $ref: getSchemaPath(SchemaDTO) - }, + type: SchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -1219,9 +1260,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) async importToTopicFromFile(@Req() req, @Response() res): Promise { @@ -1264,11 +1303,13 @@ export class SchemaApi { required: true, example: '0.0.1' }) + @ApiBody({ + description: 'A zip file containing schema to be imported.', + required: true + }) @ApiOkResponse({ description: 'Successful operation.', - schema: { - $ref: getSchemaPath(TaskDTO) - }, + type: TaskDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -1278,9 +1319,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) async importToTopicFromFileAsync(@Req() req, @Response() res): Promise { @@ -1316,13 +1355,11 @@ export class SchemaApi { type: String, description: 'Schema ID', required: true, - example: '000000000000000000000000' + example: '000000000000000000000001' }) @ApiOkResponse({ description: 'Successful operation.', - schema: { - $ref: getSchemaPath(ExportSchemaDTO) - }, + type: ExportSchemaDTO }) @ApiUnauthorizedResponse({ description: 'Unauthorized.', @@ -1332,9 +1369,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async exportMessage(@Req() req, @Response() res): Promise { @@ -1372,7 +1407,7 @@ export class SchemaApi { type: String, description: 'Schema ID', required: true, - example: '000000000000000000000000' + example: '000000000000000000000001' }) @ApiOkResponse({ description: 'Successful operation. Response zip file.' @@ -1385,9 +1420,7 @@ export class SchemaApi { }) @ApiInternalServerErrorResponse({ description: 'Internal server error.', - schema: { - $ref: getSchemaPath(InternalServerErrorDTO) - } + type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) async exportToFile(@Req() req, @Response() res): Promise { @@ -1420,7 +1453,36 @@ export class SchemaApi { } } + /** + * Create system schema + */ @Post('/system/:username') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Creates a new system schema.', + description: 'Creates a new system schema.' + ONLY_SR + }) + @ApiImplicitParam({ + name: 'username', + type: String, + description: 'username', + required: true, + example: 'username' + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: SchemaDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.CREATED) async postSystemSchema(@Body() body: SystemSchemaDTO, @Req() req, @Response() res): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -1453,7 +1515,59 @@ export class SchemaApi { } } + /** + * Get system schemas page + */ @Get('/system/:username') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Return a list of all system schemas.', + description: 'Returns all system schemas.' + ONLY_SR + }) + @ApiImplicitParam({ + name: 'username', + type: String, + description: 'username', + required: true, + example: 'username' + }) + @ApiImplicitQuery({ + name: 'pageIndex', + type: Number, + description: 'The number of pages to skip before starting to collect the result set', + required: false, + example: 0 + }) + @ApiImplicitQuery({ + name: 'pageSize', + type: Number, + description: 'The numbers of items to return', + required: false, + example: 20 + }) + @ApiOkResponse({ + description: 'Successful operation.', + isArray: true, + headers: { + 'x-total-count': { + schema: { + 'type': 'integer' + }, + description: 'Total items in the collection.' + } + }, + type: SchemaDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async getSystemSchema(@Req() req, @Response() res): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -1476,7 +1590,35 @@ export class SchemaApi { } } + /** + * Delete system schema + */ @Delete('/system/:schemaId') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Deletes the system schema with the provided schema ID.', + description: 'Deletes the system schema with the provided schema ID.' + ONLY_SR, + }) + @ApiImplicitParam({ + name: 'schemaId', + type: String, + description: 'Schema ID', + required: true, + example: '000000000000000000000001' + }) + @ApiOkResponse({ + description: 'Successful operation.', + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.NO_CONTENT) async deleteSystemSchema(@Req() req, @Response() res): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -1503,7 +1645,42 @@ export class SchemaApi { } } + /** + * Update system schema + */ @Put('/system/:schemaId') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Updates the system schema.', + description: 'Updates the system schema.' + ONLY_SR, + }) + @ApiImplicitParam({ + name: 'schemaId', + type: String, + description: 'Schema ID', + required: true, + example: '000000000000000000000001' + }) + @ApiBody({ + description: 'Object that contains a valid schema.', + required: true, + type: SchemaDTO + }) + @ApiOkResponse({ + description: 'Successful operation.', + isArray: true, + type: SchemaDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async setSystemSchema(@Req() req, @Response() res): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -1531,7 +1708,35 @@ export class SchemaApi { } } + /** + * Makes the selected scheme active. + */ @Put('/system/:schemaId/active') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Makes the selected scheme active. Other schemes of the same type become inactive', + description: 'Makes the selected scheme active. Other schemes of the same type become inactive' + ONLY_SR, + }) + @ApiImplicitParam({ + name: 'schemaId', + type: String, + description: 'Schema ID', + required: true, + example: '000000000000000000000001' + }) + @ApiOkResponse({ + description: 'Successful operation.', + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async activeSystemSchema(@Req() req: any): Promise { await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); @@ -1556,7 +1761,36 @@ export class SchemaApi { } } + /** + * Finds the schema by entity. + */ @Get('/system/entity/:schemaEntity') + @ApiSecurity('bearerAuth') + @ApiOperation({ + summary: 'Finds the schema using the schema type.', + description: 'Finds the schema using the schema type.', + }) + @ApiImplicitParam({ + name: 'schemaEntity', + enum: ['STANDARD_REGISTRY', 'USER', 'POLICY', 'MINT_TOKEN', 'WIPE_TOKEN', 'MINT_NFTOKEN'], + description: 'Entity name', + required: true, + example: 'STANDARD_REGISTRY' + }) + @ApiOkResponse({ + description: 'Successful operation.', + type: TaskDTO + }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized.', + }) + @ApiForbiddenResponse({ + description: 'Forbidden.', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error.', + type: InternalServerErrorDTO + }) @HttpCode(HttpStatus.OK) async getSchemaEntity(@Req() req, @Response() res): Promise { await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR)(req.user) diff --git a/api-gateway/src/middlewares/validation/fields-validation.ts b/api-gateway/src/middlewares/validation/fields-validation.ts index 4343e548a8..b4f083d3c1 100644 --- a/api-gateway/src/middlewares/validation/fields-validation.ts +++ b/api-gateway/src/middlewares/validation/fields-validation.ts @@ -2,37 +2,37 @@ import * as yup from 'yup'; import { UserRole, SchemaEntity } from '@guardian/interfaces'; const fieldsValidation = { - contractId: yup.string().required('The contractId field is required'), - description: yup.string().required('The description field is required'), - baseTokenId: yup.string().required('The baseTokenId field is required'), - oppositeTokenId: yup.string().nullable().typeError('The oppositeTokenId field must be a string'), - baseTokenCount: yup.string().nullable().typeError('The baseTokenCount field must be a string'), - oppositeTokenCount: yup.string().nullable().typeError('The oppositeTokenId field must be a string'), - baseTokenSerials: yup.array().typeError('The baseTokenSerials field must be an array').of(yup.number()) - .min(1, 'The baseTokenSerials field must contains at least 1 item') - .required('The baseTokenSerials field is required'), - oppositeTokenSerials: yup.array().of(yup.number()) - .nullable().when(['baseTokenId', 'oppositeTokenId'], { - is: false, - then: () => { - return yup.array().of(yup.number()).required('The field oppositeTokenSerials must be provided') - } - }), - requestId: yup.string().required('The requestId field is required'), - name: yup.string().min(1, 'The name field can not be empty').required('The name field is required'), - username: yup.string().min(1, 'The username field can not be empty').required('The username field is required'), - entity: yup.mixed() - .oneOf([SchemaEntity.STANDARD_REGISTRY, SchemaEntity.USER]).required('The entity field is required'), - password: yup.string().min(1, 'The password field can not be empty').required('The password field is required'), - messageId: yup.string().required('message ID in body is required'), - password_confirmation: yup.string().min(1, 'The password_confirmation field can not be empty') - .required('The password_confirmation field is required') - .oneOf([yup.ref('password'), null], 'Passwords must match'), - role: yup.mixed().oneOf([...Object.values(UserRole), 'ROOT_AUTHORITY']) - .required('The role field is required'), - ipfsStorageApiKey: yup.string().required('ipfsStorageApiKey field is required'), - operatorId: yup.string().required('operatorId field is required'), - operatorKey: yup.string().required('operatorKey field is required') + contractId: yup.string().required('The contractId field is required'), + description: yup.string().required('The description field is required'), + baseTokenId: yup.string().required('The baseTokenId field is required'), + oppositeTokenId: yup.string().nullable().typeError('The oppositeTokenId field must be a string'), + baseTokenCount: yup.string().nullable().typeError('The baseTokenCount field must be a string'), + oppositeTokenCount: yup.string().nullable().typeError('The oppositeTokenId field must be a string'), + baseTokenSerials: yup.array().typeError('The baseTokenSerials field must be an array').of(yup.number()) + .min(1, 'The baseTokenSerials field must contains at least 1 item') + .required('The baseTokenSerials field is required'), + oppositeTokenSerials: yup.array().of(yup.number()) + .nullable().when(['baseTokenId', 'oppositeTokenId'], { + is: false, + then: () => { + return yup.array().of(yup.number()).required('The field oppositeTokenSerials must be provided') + } + }), + requestId: yup.string().required('The requestId field is required'), + name: yup.string().min(1, 'The name field can not be empty').required('The name field is required'), + username: yup.string().min(1, 'The username field can not be empty').required('The username field is required'), + entity: yup.mixed() + .oneOf([SchemaEntity.STANDARD_REGISTRY, SchemaEntity.USER]).required('The entity field is required'), + password: yup.string().min(1, 'The password field can not be empty').required('The password field is required'), + messageId: yup.string().required('message ID in body is required'), + password_confirmation: yup.string().min(1, 'The password_confirmation field can not be empty') + .required('The password_confirmation field is required') + .oneOf([yup.ref('password'), null], 'Passwords must match'), + role: yup.mixed().oneOf([...Object.values(UserRole), 'ROOT_AUTHORITY']) + .required('The role field is required'), + ipfsStorageApiKey: yup.string().required('ipfsStorageApiKey field is required'), + operatorId: yup.string().required('operatorId field is required'), + operatorKey: yup.string().required('operatorKey field is required') }; export default fieldsValidation; diff --git a/api-gateway/src/middlewares/validation/index.ts b/api-gateway/src/middlewares/validation/index.ts index a7a15d8c59..d196aa60b4 100644 --- a/api-gateway/src/middlewares/validation/index.ts +++ b/api-gateway/src/middlewares/validation/index.ts @@ -9,7 +9,7 @@ type ValidationError = string & { errors: string[] } * @param err */ const getValidationErrors = (err: ValidationError): string[] => { - return err?.errors || [err] + return err?.errors || [err] } /** @@ -18,7 +18,7 @@ const getValidationErrors = (err: ValidationError): string[] => { * @param type */ export const prepareValidationResponse = (err, type: string = 'ValidationError') => { - return { type, message: getValidationErrors(err) }; + return { type, message: getValidationErrors(err) }; } /** @@ -26,16 +26,16 @@ export const prepareValidationResponse = (err, type: string = 'ValidationError') * @param schema */ const validate = (schema) => async (req, res, next) => { - try { - await schema.validate({ - body: req.body, - query: req.query, - params: req.params, - }, { abortEarly: false }); - return next(); - } catch (err) { - return res.status(422).json(prepareValidationResponse(err, err.name)); - } + try { + await schema.validate({ + body: req.body, + query: req.query, + params: req.params, + }, { abortEarly: false }); + return next(); + } catch (err) { + return res.status(422).json(prepareValidationResponse(err, err.name)); + } }; -export default validate +export default validate \ No newline at end of file diff --git a/api-gateway/src/middlewares/validation/schemas/analytics.ts b/api-gateway/src/middlewares/validation/schemas/analytics.ts new file mode 100644 index 0000000000..00660a4ec1 --- /dev/null +++ b/api-gateway/src/middlewares/validation/schemas/analytics.ts @@ -0,0 +1,205 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsArray, IsObject, IsString, IsNumber } from 'class-validator'; +import { Type } from 'class-transformer'; + +export class SearchPoliciesDTO { + @ApiProperty() + @IsObject() + target: any; + + @ApiProperty() + @IsObject() + result: any; +} + +export class ComparePoliciesDTO { + @ApiProperty() + @IsObject() + blocks: any; + + @ApiProperty() + @IsObject() + groups: any; + + @ApiProperty() + @IsObject() + left: any; + + @ApiProperty() + @IsObject() + right: any; + + @ApiProperty() + @IsObject() + roles: any; + + @ApiProperty() + @IsObject() + tokens: any; + + @ApiProperty() + @IsObject() + topics: any; + + @ApiProperty() + @IsObject() + total: any; +} + +export class CompareModulesDTO { + @ApiProperty() + @IsObject() + blocks: any; + + @ApiProperty() + @IsObject() + left: any; + + @ApiProperty() + @IsObject() + right: any; + + @ApiProperty() + @IsObject() + inputEvents: any; + + @ApiProperty() + @IsObject() + outputEvents: any; + + @ApiProperty() + @IsObject() + variables: any; + + @ApiProperty() + @IsObject() + total: any; +} + +export class CompareSchemasDTO { + @ApiProperty() + @IsObject() + fields: any; + + @ApiProperty() + @IsObject() + left: any; + + @ApiProperty() + @IsObject() + right: any; + + @ApiProperty() + @IsObject() + total: any; +} + +export class CompareDocumentsDTO { + @ApiProperty() + @IsObject() + documents: any; + + @ApiProperty() + @IsObject() + left: any; + + @ApiProperty() + @IsObject() + right: any; + + @ApiProperty() + @IsObject() + total: any; +} + +export class FilterSearchPoliciesDTO { + @ApiProperty() + @IsString() + policyId: string; +} + +export class FilterPoliciesDTO { + @ApiProperty() + @IsString() + policyId1: string; + + @ApiProperty() + @IsString() + policyId2: string; + + @ApiProperty({ type: () => String }) + @IsArray() + @Type(() => String) + policyIds: string[]; + + @ApiProperty() + @IsNumber() + eventsLvl: number; + + @ApiProperty() + @IsNumber() + propLvl: number; + + @ApiProperty() + @IsNumber() + childrenLvl: number; + + @ApiProperty() + @IsNumber() + idLvl: number; +} + +export class FilterModulesDTO { + @ApiProperty() + @IsString() + moduleId1: string; + + @ApiProperty() + @IsString() + moduleId2: string; + + @ApiProperty() + @IsNumber() + eventsLvl: number; + + @ApiProperty() + @IsNumber() + propLvl: number; + + @ApiProperty() + @IsNumber() + childrenLvl: number; + + @ApiProperty() + @IsNumber() + idLvl: number; +} + +export class FilterSchemasDTO { + @ApiProperty() + @IsString() + schemaId1: string; + + @ApiProperty() + @IsString() + schemaId2: string; + + @ApiProperty() + @IsNumber() + idLvl: number; +} + +export class FilterDocumentsDTO { + @ApiProperty() + @IsString() + documentId1: string; + + @ApiProperty() + @IsString() + documentId2: string; + + @ApiProperty({ type: () => String }) + @IsArray() + @Type(() => String) + documentIds: string[]; +} \ No newline at end of file diff --git a/api-gateway/src/middlewares/validation/schemas/index.ts b/api-gateway/src/middlewares/validation/schemas/index.ts index e2b86f0322..277a67f973 100644 --- a/api-gateway/src/middlewares/validation/schemas/index.ts +++ b/api-gateway/src/middlewares/validation/schemas/index.ts @@ -7,4 +7,5 @@ export * from './schemas' export * from './settings' export * from './suggestions' export * from './task' -export * from './tool' \ No newline at end of file +export * from './tool' +export * from './analytics' \ No newline at end of file diff --git a/api-gateway/src/middlewares/validation/schemas/schemas.ts b/api-gateway/src/middlewares/validation/schemas/schemas.ts index b2b5cb5684..352078e9fb 100644 --- a/api-gateway/src/middlewares/validation/schemas/schemas.ts +++ b/api-gateway/src/middlewares/validation/schemas/schemas.ts @@ -121,4 +121,18 @@ export class ExportSchemaDTO { @ApiProperty() @IsString() messageId: string; +} + +export class VersionSchemaDTO { + @ApiProperty() + @IsString() + @IsNotEmpty() + version: string; +} + +export class MessageSchemaDTO { + @ApiProperty() + @IsString() + @IsNotEmpty() + messageId: string; } \ No newline at end of file diff --git a/api-tests/package.json b/api-tests/package.json index d358d638dc..85351337e3 100644 --- a/api-tests/package.json +++ b/api-tests/package.json @@ -1,6 +1,6 @@ { "name": "api-tests", - "version": "2.17.0-prerelease", + "version": "2.17.0", "description": "API Tests", "main": "index.js", "scripts": { @@ -25,6 +25,5 @@ "gulp-rename": "^2.0.0", "gulp-sourcemaps": "^3.0.0", "gulp-typescript": "^6.0.0-alpha.1" - }, - "stableVersion": "2.16.0" + } } diff --git a/auth-service/package.json b/auth-service/package.json index 195ec55489..4e0bedf8b3 100644 --- a/auth-service/package.json +++ b/auth-service/package.json @@ -6,8 +6,8 @@ }, "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", + "@guardian/interfaces": "^2.17.0", "@meeco/cryppo": "^2.0.2", "@mikro-orm/core": "5.7.12", "@mikro-orm/mongodb": "5.7.12", @@ -69,6 +69,5 @@ "start": "node dist/index.js", "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ui-service.xml" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/common/package.json b/common/package.json index 8f7e51b2dc..28b74b9aac 100644 --- a/common/package.json +++ b/common/package.json @@ -5,7 +5,7 @@ "@azure/identity": "^3.2.2", "@azure/keyvault-secrets": "^4.7.0", "@google-cloud/secret-manager": "^4.2.2", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/interfaces": "^2.17.0", "@hashgraph/sdk": "2.24.2", "@mattrglobal/jsonld-signatures-bbs": "^1.1.2", "@meeco/cryppo": "^2.0.2", @@ -77,6 +77,5 @@ "test:local": "mocha tests/**/*.test.js --exit", "test:stability": "mocha tests/stability.test.js" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/common/src/entity/tool.ts b/common/src/entity/tool.ts index 6ffe025fe2..22920ae00b 100644 --- a/common/src/entity/tool.ts +++ b/common/src/entity/tool.ts @@ -81,6 +81,12 @@ export class PolicyTool extends BaseEntity { @Property({ nullable: true }) codeVersion?: string; + /** + * Tool topic id + */ + @Property({ nullable: true }) + tagsTopicId?: string; + /** * Set policy defaults */ diff --git a/common/src/hedera-modules/message/message-body.interface.ts b/common/src/hedera-modules/message/message-body.interface.ts index c388062019..925c8d0c2a 100644 --- a/common/src/hedera-modules/message/message-body.interface.ts +++ b/common/src/hedera-modules/message/message-body.interface.ts @@ -497,4 +497,8 @@ export interface ToolMessageBody extends MessageBody { * URI */ uri: string; + /** + * Tags topic ID + */ + tagsTopicId: string; } \ No newline at end of file diff --git a/common/src/hedera-modules/message/tool-message.ts b/common/src/hedera-modules/message/tool-message.ts index b6dfe4792e..e28537172e 100644 --- a/common/src/hedera-modules/message/tool-message.ts +++ b/common/src/hedera-modules/message/tool-message.ts @@ -39,6 +39,10 @@ export class ToolMessage extends Message { * @private */ public toolTopicId: string; + /** + * Tags topic ID + */ + public tagsTopicId: string; constructor(type: MessageType.Tool, action: MessageAction) { super(action, type); @@ -59,6 +63,7 @@ export class ToolMessage extends Message { this.hash = model.hash; this.document = zip; this.toolTopicId = model.topicId; + this.tagsTopicId = model.tagsTopicId; } /** @@ -84,6 +89,7 @@ export class ToolMessage extends Message { owner: this.owner, hash: this.hash, topicId: this.toolTopicId?.toString(), + tagsTopicId: this.tagsTopicId, cid: this.getDocumentUrl(UrlType.cid), uri: this.getDocumentUrl(UrlType.url) } @@ -146,6 +152,7 @@ export class ToolMessage extends Message { message.owner = json.owner; message.hash = json.hash; message.toolTopicId = json.topicId; + message.tagsTopicId = json.tagsTopicId; if (json.cid) { const urls = [{ @@ -194,6 +201,7 @@ export class ToolMessage extends Message { result.hash = this.hash; result.document = this.document; result.toolTopicId = this.toolTopicId; + result.tagsTopicId = this.tagsTopicId; return result; } diff --git a/frontend/package.json b/frontend/package.json index 95f559625d..3f4722bb7d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -68,6 +68,5 @@ "test": "ng test", "watch": "ng build --watch --configuration development --output-path ../www-data" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/frontend/src/app/components/notification/notification.component.scss b/frontend/src/app/components/notification/notification.component.scss index b0f3111e5f..e12a4b5ae7 100644 --- a/frontend/src/app/components/notification/notification.component.scss +++ b/frontend/src/app/components/notification/notification.component.scss @@ -24,7 +24,7 @@ .notification-menu-header { display: flex; justify-content: space-between; - align-items: end; + align-items: flex-end; padding: 0 5px; &__title { @@ -134,7 +134,7 @@ .progress-bar { display: flex; gap: 10px; - align-items: end; + align-items: flex-end; grid-area: progress; margin-bottom: 3px; diff --git a/frontend/src/app/modules/common/async-progress/async-progress.component.css b/frontend/src/app/modules/common/async-progress/async-progress.component.css index e565425607..7a70f10265 100644 --- a/frontend/src/app/modules/common/async-progress/async-progress.component.css +++ b/frontend/src/app/modules/common/async-progress/async-progress.component.css @@ -27,6 +27,13 @@ height: 80%; } +.loading-progress-info { + height: 100%; + overflow-y: auto; + padding-right: 10px; + padding-top: 10px; +} + .task-not-found { display: flex; gap: 10px; @@ -41,4 +48,4 @@ .task-not-found__label { font-size: 60px; -} \ No newline at end of file +} diff --git a/frontend/src/app/modules/common/async-progress/async-progress.component.html b/frontend/src/app/modules/common/async-progress/async-progress.component.html index 3ebcf0ee58..87c1bfd3da 100644 --- a/frontend/src/app/modules/common/async-progress/async-progress.component.html +++ b/frontend/src/app/modules/common/async-progress/async-progress.component.html @@ -3,7 +3,7 @@
-
+
INFO: {{ @@ -18,4 +18,4 @@
searchTask not found
-
\ No newline at end of file +
diff --git a/frontend/src/app/modules/common/async-progress/async-progress.component.ts b/frontend/src/app/modules/common/async-progress/async-progress.component.ts index 79d5ba8b21..142a4bd9a9 100644 --- a/frontend/src/app/modules/common/async-progress/async-progress.component.ts +++ b/frontend/src/app/modules/common/async-progress/async-progress.component.ts @@ -144,7 +144,7 @@ export class AsyncProgressComponent implements OnInit, OnDestroy { queryParams[key] = value; } } - this.router.navigate(path, {queryParams}); + this.router.navigate(path, { queryParams }); } handleResult(result: any) { @@ -178,6 +178,14 @@ export class AsyncProgressComponent implements OnInit, OnDestroy { replaceUrl: true, }); break; + case TaskAction.CREATE_TOOL: + this.router.navigate(['policy-configuration'], { + queryParams: { + toolId: result, + }, + replaceUrl: true, + }); + break; case TaskAction.IMPORT_POLICY_FILE: case TaskAction.IMPORT_POLICY_MESSAGE: this.router.navigate(['policy-configuration'], { @@ -236,8 +244,43 @@ export class AsyncProgressComponent implements OnInit, OnDestroy { }); } break; + case TaskAction.PUBLISH_TOOL: + if (result) { + const { isValid, errors, tool } = result; + if (!isValid) { + let text = []; + const blocks = errors.blocks; + const invalidBlocks = blocks.filter( + (block: any) => !block.isValid + ); + for (let i = 0; i < invalidBlocks.length; i++) { + const block = invalidBlocks[i]; + for (let j = 0; j < block.errors.length; j++) { + const error = block.errors[j]; + if (block.id) { + text.push( + `
${block.id}: ${error}
` + ); + } else { + text.push(`
${error}
`); + } + } + } + this.informService.errorMessage( + text.join(''), + 'The tool is invalid' + ); + } + this.router.navigate(['policy-configuration'], { + queryParams: { + toolId: tool?.id + }, + replaceUrl: true, + }); + } + break; case TaskAction.DELETE_POLICY: - this.router.navigate(['policy-viewer'], { + this.router.navigate(['policy-viewer'], { replaceUrl: true, }); break; @@ -252,7 +295,7 @@ export class AsyncProgressComponent implements OnInit, OnDestroy { this.redirect(this.last); return; } - this.router.navigate(['schemas'], { + this.router.navigate(['schemas'], { replaceUrl: true, }); break; @@ -275,14 +318,14 @@ export class AsyncProgressComponent implements OnInit, OnDestroy { case TaskAction.CONNECT_USER: this.router.navigate([ this.userRole === UserRole.USER ? 'user-profile' : 'config', - ], { + ], { replaceUrl: true, }); break; case TaskAction.DELETE_TOKEN: case TaskAction.UPDATE_TOKEN: case TaskAction.CREATE_TOKEN: - this.router.navigate(['tokens'], { + this.router.navigate(['tokens'], { replaceUrl: true, }); break; @@ -293,7 +336,7 @@ export class AsyncProgressComponent implements OnInit, OnDestroy { case TaskAction.WIZARD_CREATE_POLICY: case TaskAction.PUBLISH_POLICY: case TaskAction.DELETE_POLICY: - this.router.navigate(['policy-viewer'], { + this.router.navigate(['policy-viewer'], { replaceUrl: true, }); break; @@ -301,7 +344,7 @@ export class AsyncProgressComponent implements OnInit, OnDestroy { case TaskAction.PUBLISH_SCHEMA: case TaskAction.IMPORT_SCHEMA_FILE: case TaskAction.IMPORT_SCHEMA_MESSAGE: - this.router.navigate(['schemas'], { + this.router.navigate(['schemas'], { replaceUrl: true, }); break; diff --git a/frontend/src/app/modules/policy-engine/helpers/compare-modules-dialog/compare-modules-dialog.component.ts b/frontend/src/app/modules/policy-engine/helpers/compare-modules-dialog/compare-modules-dialog.component.ts index d88be30384..e412003c45 100644 --- a/frontend/src/app/modules/policy-engine/helpers/compare-modules-dialog/compare-modules-dialog.component.ts +++ b/frontend/src/app/modules/policy-engine/helpers/compare-modules-dialog/compare-modules-dialog.component.ts @@ -31,6 +31,9 @@ export class CompareModulesDialogComponent { ngOnInit() { this.loading = false; + setTimeout(() => { + this.onChange(); + }); } setData(data: any) { diff --git a/frontend/src/app/modules/policy-engine/helpers/compare-policy-dialog/compare-policy-dialog.component.ts b/frontend/src/app/modules/policy-engine/helpers/compare-policy-dialog/compare-policy-dialog.component.ts index a10eceb13c..18c6d9cf8f 100644 --- a/frontend/src/app/modules/policy-engine/helpers/compare-policy-dialog/compare-policy-dialog.component.ts +++ b/frontend/src/app/modules/policy-engine/helpers/compare-policy-dialog/compare-policy-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject } from '@angular/core'; +import { ChangeDetectorRef, Component, Inject } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; @Component({ @@ -20,6 +20,7 @@ export class ComparePolicyDialog { constructor( public dialogRef: MatDialogRef, + private changeDetector: ChangeDetectorRef, @Inject(MAT_DIALOG_DATA) public data: any) { this.policy = data.policy; this.policies = data.policies || []; @@ -34,6 +35,9 @@ export class ComparePolicyDialog { ngOnInit() { this.loading = false; + setTimeout(() => { + this.onChange(); + }); } setData(data: any) { @@ -62,5 +66,6 @@ export class ComparePolicyDialog { } else { this.list1 = this.policies; } + this.changeDetector.detectChanges(); } } \ No newline at end of file diff --git a/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts b/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts index c5fdb0abbb..bacd8204ff 100644 --- a/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts +++ b/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts @@ -1,8 +1,6 @@ import { CdkDropList } from '@angular/cdk/drag-drop'; import { ChangeDetectorRef, Component, HostListener, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { MatIconRegistry } from '@angular/material/icon'; -import { DomSanitizer } from '@angular/platform-browser'; import { ActivatedRoute, Router } from '@angular/router'; import { Schema, SchemaHelper, Token } from '@guardian/interfaces'; import * as yaml from 'js-yaml'; @@ -18,7 +16,17 @@ import { NewModuleDialog } from '../../helpers/new-module-dialog/new-module-dial import { SaveBeforeDialogComponent } from '../../helpers/save-before-dialog/save-before-dialog.component'; import { PolicyAction, SavePolicyDialog } from '../../helpers/save-policy-dialog/save-policy-dialog.component'; import { RegisteredService } from '../../services/registered.service'; -import { Options, PolicyBlock, PolicyTemplate, PolicyModule, PolicyStorage, ModuleTemplate, Theme, ThemeRule, ToolTemplate } from '../../structures'; +import { + Options, + PolicyBlock, + PolicyTemplate, + PolicyModule, + PolicyStorage, + ModuleTemplate, + Theme, + ThemeRule, + ToolTemplate +} from '../../structures'; import { PolicyTreeComponent } from '../policy-tree/policy-tree.component'; import { ThemeService } from '../../../../services/theme.service'; import { WizardMode, WizardService } from 'src/app/modules/policy-engine/services/wizard.service'; @@ -179,8 +187,6 @@ export class PolicyConfigurationComponent implements OnInit { private router: Router, private dialog: MatDialog, private changeDetector: ChangeDetectorRef, - private domSanitizer: DomSanitizer, - private matIconRegistry: MatIconRegistry, private informService: InformService, private registeredService: RegisteredService, private themeService: ThemeService, diff --git a/frontend/src/app/modules/policy-engine/policy-configuration/policy-settings/policy-settings.component.scss b/frontend/src/app/modules/policy-engine/policy-configuration/policy-settings/policy-settings.component.scss index 8f1409393d..61745abf15 100644 --- a/frontend/src/app/modules/policy-engine/policy-configuration/policy-settings/policy-settings.component.scss +++ b/frontend/src/app/modules/policy-engine/policy-configuration/policy-settings/policy-settings.component.scss @@ -492,7 +492,7 @@ border-bottom: 1px solid #000; height: 51px; overflow: hidden; - align-items: end; + align-items: flex-end; display: flex; padding-bottom: 20px; } diff --git a/frontend/src/app/modules/policy-engine/structures/policy-models/module/block.model.ts b/frontend/src/app/modules/policy-engine/structures/policy-models/module/block.model.ts index 624eecc5b6..0637ba4947 100644 --- a/frontend/src/app/modules/policy-engine/structures/policy-models/module/block.model.ts +++ b/frontend/src/app/modules/policy-engine/structures/policy-models/module/block.model.ts @@ -619,7 +619,10 @@ export class PolicyModule extends PolicyBlock { blockType: BlockType.Tool, defaultActive: true, hash: template.hash, - messageId: template.messageId + messageId: template.messageId, + inputEvents: template.config?.inputEvents, + outputEvents: template.config?.outputEvents, + variables: template.config?.variables } const tool = TemplateUtils.buildBlock(config, null, this) as PolicyTool; this._tagMap[tool.tag] = tool; @@ -651,7 +654,7 @@ export class PolicyModule extends PolicyBlock { } public setEnvironments(env: any): void { - if(env) { + if (env) { this._schemas = env.schemas; this._tools = env.tools; this._tokens = env.tokens; diff --git a/frontend/src/app/modules/policy-engine/structures/policy-models/policy/policy.model.ts b/frontend/src/app/modules/policy-engine/structures/policy-models/policy/policy.model.ts index 01186a4ff0..18f9291839 100644 --- a/frontend/src/app/modules/policy-engine/structures/policy-models/policy/policy.model.ts +++ b/frontend/src/app/modules/policy-engine/structures/policy-models/policy/policy.model.ts @@ -524,7 +524,10 @@ export class PolicyTemplate { blockType: BlockType.Tool, defaultActive: true, hash: template.hash, - messageId: template.messageId + messageId: template.messageId, + inputEvents: template.config?.inputEvents, + outputEvents: template.config?.outputEvents, + variables: template.config?.variables } const tool = TemplateUtils.buildBlock(config, null, this) as PolicyTool; this._tagMap[tool.tag] = tool; diff --git a/frontend/src/app/modules/policy-engine/structures/policy-models/tool/block.model.ts b/frontend/src/app/modules/policy-engine/structures/policy-models/tool/block.model.ts index b755e2e35b..c9a8ebf25d 100644 --- a/frontend/src/app/modules/policy-engine/structures/policy-models/tool/block.model.ts +++ b/frontend/src/app/modules/policy-engine/structures/policy-models/tool/block.model.ts @@ -631,7 +631,10 @@ export class PolicyTool extends PolicyBlock { blockType: BlockType.Tool, defaultActive: true, hash: template.hash, - messageId: template.messageId + messageId: template.messageId, + inputEvents: template.config?.inputEvents, + outputEvents: template.config?.outputEvents, + variables: template.config?.variables } const tool = TemplateUtils.buildBlock(config, null, this) as PolicyTool; this._tagMap[tool.tag] = tool; diff --git a/frontend/src/app/modules/policy-engine/tools-list/tools-list.component.ts b/frontend/src/app/modules/policy-engine/tools-list/tools-list.component.ts index a71e720454..fa7acef0b5 100644 --- a/frontend/src/app/modules/policy-engine/tools-list/tools-list.component.ts +++ b/frontend/src/app/modules/policy-engine/tools-list/tools-list.component.ts @@ -1,7 +1,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; -import { IUser, SchemaHelper, TagType } from '@guardian/interfaces'; +import { GenerateUUIDv4, IUser, SchemaHelper, TagType } from '@guardian/interfaces'; import { forkJoin } from 'rxjs'; import { ConfirmationDialogComponent } from 'src/app/modules/common/confirmation-dialog/confirmation-dialog.component'; import { InformService } from 'src/app/services/inform.service'; @@ -43,7 +43,7 @@ export class ToolsListComponent implements OnInit, OnDestroy { 'name', 'description', 'topic', - // 'tags', + 'tags', 'schemas', 'status', 'operation', @@ -249,12 +249,14 @@ export class ToolsListComponent implements OnInit, OnDestroy { description: result.description, menu: "show", config: { + id: GenerateUUIDv4(), blockType: 'tool' } } this.loading = true; - this.toolsService.create(tool).subscribe((result) => { - this.loadAllTools(); + this.toolsService.pushCreate(tool).subscribe((result) => { + const { taskId, expectation } = result; + this.router.navigate(['/task', taskId]); }, (e) => { this.loading = false; }); @@ -286,32 +288,13 @@ export class ToolsListComponent implements OnInit, OnDestroy { public publishTool(element: any) { this.loading = true; - this.toolsService.publish(element.id).subscribe((result) => { - const { isValid, errors } = result; - if (!isValid) { - let text = []; - const blocks = errors.blocks; - const invalidBlocks = blocks.filter( - (block: any) => !block.isValid - ); - for (let i = 0; i < invalidBlocks.length; i++) { - const block = invalidBlocks[i]; - for ( - let j = 0; - j < block.errors.length; - j++ - ) { - const error = block.errors[j]; - if (block.id) { - text.push(`
${block.id}: ${error}
`); - } else { - text.push(`
${error}
`); - } - } + this.toolsService.pushPublish(element.id).subscribe((result) => { + const { taskId, expectation } = result; + this.router.navigate(['task', taskId], { + queryParams: { + last: btoa(location.href) } - this.informService.errorMessage(text.join(''), 'The tool is invalid'); - } - this.loadAllTools(); + }); }, (e) => { this.loading = false; }); diff --git a/frontend/src/app/services/tools.service.ts b/frontend/src/app/services/tools.service.ts index 9914a1df65..eb2b75a3a7 100644 --- a/frontend/src/app/services/tools.service.ts +++ b/frontend/src/app/services/tools.service.ts @@ -29,6 +29,10 @@ export class ToolsService { return this.http.post(`${this.url}/`, tool); } + public pushCreate(tool: any): Observable<{ taskId: string, expectation: number }> { + return this.http.post(`${this.url}/push`, tool); + } + public menuList(): Observable { return this.http.get(`${this.url}/menu/all`); } diff --git a/frontend/src/app/views/admin/about-view/about-view.component.css b/frontend/src/app/views/admin/about-view/about-view.component.css index 7577f1a034..bea18547ae 100644 --- a/frontend/src/app/views/admin/about-view/about-view.component.css +++ b/frontend/src/app/views/admin/about-view/about-view.component.css @@ -32,7 +32,7 @@ .title-column { max-width: 300px; font-weight: 500; - align-items: end; + align-items: flex-end; } .value-column { diff --git a/frontend/src/app/views/schemas/schemas.component.html b/frontend/src/app/views/schemas/schemas.component.html index decd21fe6e..c6091c0921 100644 --- a/frontend/src/app/views/schemas/schemas.component.html +++ b/frontend/src/app/views/schemas/schemas.component.html @@ -52,7 +52,6 @@ Tools All - No binding {{tool.name}} ({{tool.topicId}}) diff --git a/guardian-service/package.json b/guardian-service/package.json index 6e06a965bb..2875a38139 100644 --- a/guardian-service/package.json +++ b/guardian-service/package.json @@ -12,8 +12,8 @@ }, "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", + "@guardian/interfaces": "^2.17.0", "@hashgraph/sdk": "2.24.2", "@mattrglobal/jsonld-signatures-bbs": "^1.1.2", "@meeco/cryppo": "^2.0.2", @@ -92,6 +92,5 @@ "test:local": "mocha tests/**/*.test.js --exit", "test:stability": "mocha tests/stability.test.js" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/guardian-service/src/api/helpers/tool-import-export-helper.ts b/guardian-service/src/api/helpers/tool-import-export-helper.ts index 22e84d854b..1813307ee8 100644 --- a/guardian-service/src/api/helpers/tool-import-export-helper.ts +++ b/guardian-service/src/api/helpers/tool-import-export-helper.ts @@ -129,9 +129,9 @@ export async function importToolByMessage( } const toolTags = components.tags?.filter((t: any) => t.entity === TagType.Tool) || []; - if (message.toolTopicId) { + if (message.tagsTopicId) { const tagMessages = await messageServer.getMessages( - message.toolTopicId, + message.tagsTopicId, MessageType.Tag, MessageAction.PublishTag ); diff --git a/guardian-service/src/api/tag.service.ts b/guardian-service/src/api/tag.service.ts index 9112d97204..df4d4442db 100644 --- a/guardian-service/src/api/tag.service.ts +++ b/guardian-service/src/api/tag.service.ts @@ -9,16 +9,26 @@ import { MessageType, PolicyModule as ModuleCollection, Policy as PolicyCollection, + PolicyTool as PolicyToolCollection, Schema as SchemaCollection, + Token as TokenCollection, Tag, TagMessage, - Token as TokenCollection, TopicConfig, UrlType, Users, VcHelper, } from '@guardian/common'; -import { GenerateUUIDv4, IRootConfig, MessageAPI, Schema, SchemaCategory, SchemaHelper, SchemaStatus, TagType } from '@guardian/interfaces'; +import { + GenerateUUIDv4, + IRootConfig, + MessageAPI, + Schema, + SchemaCategory, + SchemaHelper, + SchemaStatus, + TagType +} from '@guardian/interfaces'; /** * Publish schema tags @@ -104,6 +114,32 @@ export async function publishTokenTags( } } +/** + * Publish tool tags + * @param tool + * @param messageServer + */ +export async function publishToolTags( + tool: PolicyToolCollection, + user: IRootConfig +): Promise { + const filter: any = { + localTarget: tool.id, + entity: TagType.Tool, + status: 'Draft' + } + const tags = await DatabaseServer.getTags(filter); + const topic = await DatabaseServer.getTopicById(tool.tagsTopicId); + const topicConfig = await TopicConfig.fromObject(topic, true); + const messageServer = new MessageServer(user.hederaAccountId, user.hederaAccountKey) + .setTopicObject(topicConfig); + for (const tag of tags) { + tag.target = tool.tagsTopicId; + await publishTag(tag, messageServer); + await DatabaseServer.updateTag(tag); + } +} + /** * Publish module tags * @param module @@ -281,6 +317,18 @@ export async function getTarget(entity: TagType, id: string): Promise<{ return null; } } + case TagType.Tool: { + const item = await DatabaseServer.getToolById(id); + if (item) { + return { + id: item.id.toString(), + target: item.messageId, + topicId: item.tagsTopicId + }; + } else { + return null; + } + } default: return null; } diff --git a/guardian-service/src/api/tool.service.ts b/guardian-service/src/api/tool.service.ts index 59c6b131e6..cfc42960b9 100644 --- a/guardian-service/src/api/tool.service.ts +++ b/guardian-service/src/api/tool.service.ts @@ -35,6 +35,7 @@ import { ToolValidator } from '@policy-engine/block-validators/tool-validator'; import { PolicyConverterUtils } from '@policy-engine/policy-converter-utils'; import { importToolByFile, importToolByMessage } from './helpers'; import * as crypto from 'crypto'; +import { publishToolTags } from './tag.service'; /** * Sha256 @@ -181,6 +182,20 @@ export async function publishTool( notifier.completedAndStart('Publish schemas'); tool = await publishSchemas(tool, owner, root, notifier); + notifier.completedAndStart('Create tags topic'); + const topicHelper = new TopicHelper(root.hederaAccountId, root.hederaAccountKey); + const tagsTopic = await topicHelper.create({ + type: TopicType.TagsTopic, + name: tool.name || TopicType.TagsTopic, + description: tool.description || TopicType.TagsTopic, + owner, + policyId: tool.id.toString(), + policyUUID: tool.uuid + }, { admin: true, submit: false }); + await tagsTopic.saveKeys(); + await DatabaseServer.saveTopic(tagsTopic.toObject()); + tool.tagsTopicId = tagsTopic.topicId; + notifier.completedAndStart('Generate file'); tool = updateToolConfig(tool); const zip = await ToolImportExport.generate(tool); @@ -199,6 +214,13 @@ export async function publishTool( const result = await messageServer .sendMessage(message); + notifier.completedAndStart('Publish tags'); + try { + await publishToolTags(tool, root); + } catch (error) { + logger.error(error, ['GUARDIAN_SERVICE, TAGS']); + } + notifier.completedAndStart('Saving in DB'); tool.messageId = result.getId(); tool.status = ModuleStatus.PUBLISHED; @@ -312,7 +334,7 @@ export async function createTool( owner, targetId: tool.id.toString(), targetUUID: tool.uuid - }); + }, { admin: true, submit: true }); await topic.saveKeys(); notifier.completedAndStart('Create tool in Hedera'); @@ -462,7 +484,9 @@ export async function toolsAPI(): Promise { 'topicId', 'hash', 'messageId', - 'owner' + 'owner', + 'config', + 'configFileId' ] }); const ids = tools.map(t => t.topicId); @@ -480,6 +504,13 @@ export async function toolsAPI(): Promise { ); const map = new Map(); for (const tool of tools) { + if (tool.config) { + tool.config = { + inputEvents: tool.config.inputEvents, + outputEvents: tool.config.outputEvents, + variables: tool.config.variables + } + } tool.schemas = []; map.set(tool.topicId, tool); } diff --git a/interfaces/package.json b/interfaces/package.json index 9a359c13f1..1bc203151b 100644 --- a/interfaces/package.json +++ b/interfaces/package.json @@ -32,6 +32,5 @@ "prepack": "npm run build", "test": "echo \"Error: no test specified\" && exit 1" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/interfaces/src/type/topic.type.ts b/interfaces/src/type/topic.type.ts index de1b7319a4..26ff76d430 100644 --- a/interfaces/src/type/topic.type.ts +++ b/interfaces/src/type/topic.type.ts @@ -13,4 +13,5 @@ export enum TopicType { ModuleTopic = 'MODULE_TOPIC', ContractTopic = 'CONTRACT_TOPIC', ToolTopic = 'TOOL_TOPIC', + TagsTopic = 'TAGS_TOPIC' } diff --git a/logger-service/package.json b/logger-service/package.json index b34c2d4beb..375c08a244 100644 --- a/logger-service/package.json +++ b/logger-service/package.json @@ -1,8 +1,8 @@ { "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", + "@guardian/interfaces": "^2.17.0", "@mikro-orm/core": "5.7.12", "@mikro-orm/mongodb": "5.7.12", "@nestjs/common": "^9.4.1", @@ -48,6 +48,5 @@ "start": "node dist/index.js", "watch": "nodemon src/index.ts" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/mrv-sender/package.json b/mrv-sender/package.json index 3964f3f60c..3d148e8690 100644 --- a/mrv-sender/package.json +++ b/mrv-sender/package.json @@ -1,7 +1,7 @@ { "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", "@transmute/credentials-context": "0.7.0-unstable.80", "@transmute/did-context": "0.7.0-unstable.80", "@transmute/ed25519-signature-2018": "0.7.0-unstable.80", @@ -39,6 +39,5 @@ "dev:docker": "nodemon .", "start": "node dist/index.js" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/notification-service/package.json b/notification-service/package.json index 8bfa713c4b..554b837ec9 100644 --- a/notification-service/package.json +++ b/notification-service/package.json @@ -1,8 +1,8 @@ { "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", + "@guardian/interfaces": "^2.17.0", "@mikro-orm/core": "5.7.12", "@mikro-orm/mongodb": "5.7.12", "@nestjs/common": "^9.4.1", @@ -47,6 +47,5 @@ "start": "node dist/index.js", "watch": "nodemon src/index.ts" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/package.json b/package.json index 62d57a7970..3561a84fb8 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,5 @@ "api-tests", "notification-service" ], - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/policy-service/package.json b/policy-service/package.json index d910f5381e..27d8f31554 100644 --- a/policy-service/package.json +++ b/policy-service/package.json @@ -11,8 +11,8 @@ }, "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "2.17.0-prerelease", - "@guardian/interfaces": "2.17.0-prerelease", + "@guardian/common": "2.17.0", + "@guardian/interfaces": "2.17.0", "@hashgraph/sdk": "2.24.2", "@mattrglobal/jsonld-signatures-bbs": "^1.1.2", "@meeco/cryppo": "2.0.2", @@ -91,6 +91,5 @@ "test:local": "mocha tests/**/*.test.js", "test:stability": "mocha tests/stability.test.js" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/swagger-analytics.yaml b/swagger-analytics.yaml index 7c57036e59..ec258958eb 100644 --- a/swagger-analytics.yaml +++ b/swagger-analytics.yaml @@ -208,7 +208,7 @@ info: the heart of the Guardian solution is a sophisticated Policy Workflow Engine (PWE) that enables applications to offer a requirements-based tokenization implementation. - version: 2.16.0 + version: 2.17.0-prerelease contact: name: API developer url: https://envisionblockchain.com diff --git a/swagger.yaml b/swagger.yaml index e34cf97de5..fb4931c9f1 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -7293,7 +7293,7 @@ info: the heart of the Guardian solution is a sophisticated Policy Workflow Engine (PWE) that enables applications to offer a requirements-based tokenization implementation. - version: 2.16.0 + version: 2.17.0-prerelease contact: name: API developer url: https://envisionblockchain.com diff --git a/topic-viewer/package.json b/topic-viewer/package.json index 9f4b5ed974..9fb16e8cfd 100644 --- a/topic-viewer/package.json +++ b/topic-viewer/package.json @@ -29,6 +29,5 @@ "dev": "tsc -w", "start": "node dist/index.js" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/tree-viewer/package.json b/tree-viewer/package.json index 7ddd604cc8..fda5187bb9 100644 --- a/tree-viewer/package.json +++ b/tree-viewer/package.json @@ -27,6 +27,5 @@ "dev": "tsc -w", "start": "node dist/index.js" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/worker-service/package.json b/worker-service/package.json index 338344a416..dd14c08716 100644 --- a/worker-service/package.json +++ b/worker-service/package.json @@ -1,8 +1,8 @@ { "author": "Envision Blockchain Solutions ", "dependencies": { - "@guardian/common": "^2.17.0-prerelease", - "@guardian/interfaces": "^2.17.0-prerelease", + "@guardian/common": "^2.17.0", + "@guardian/interfaces": "^2.17.0", "@hashgraph/sdk": "2.24.2", "@nestjs/common": "^9.4.1", "@nestjs/core": "^9.4.1", @@ -59,6 +59,5 @@ "start": "node dist/index.js", "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/worker-service.xml --exit" }, - "version": "2.17.0-prerelease", - "stableVersion": "2.16.0" + "version": "2.17.0" } diff --git a/worker-service/tests/network-tests/hedera-sdk-helper.test.js b/worker-service/tests/network-tests/hedera-sdk-helper.test.js index af335cb9f0..f87fb590a0 100644 --- a/worker-service/tests/network-tests/hedera-sdk-helper.test.js +++ b/worker-service/tests/network-tests/hedera-sdk-helper.test.js @@ -16,7 +16,7 @@ async function delay(ms) { } describe('Hedera SDK Helper', function () { - const transactionTimeout = 30 * 1000; + const transactionTimeout = 90 * 1000; let sdk, accountId, accountKey, tokenId, account2Id, account2Key, token2Id, nft; diff --git a/yarn.lock b/yarn.lock index 025f1aca44..9d8de4adb1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -887,7 +887,7 @@ __metadata: languageName: node linkType: hard -"@guardian/common@2.17.0-prerelease, @guardian/common@^2.17.0-prerelease, @guardian/common@workspace:common": +"@guardian/common@2.17.0, @guardian/common@^2.17.0, @guardian/common@workspace:common": version: 0.0.0-use.local resolution: "@guardian/common@workspace:common" dependencies: @@ -895,7 +895,7 @@ __metadata: "@azure/identity": ^3.2.2 "@azure/keyvault-secrets": ^4.7.0 "@google-cloud/secret-manager": ^4.2.2 - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/interfaces": ^2.17.0 "@hashgraph/sdk": 2.24.2 "@mattrglobal/jsonld-signatures-bbs": ^1.1.2 "@meeco/cryppo": ^2.0.2 @@ -949,7 +949,7 @@ __metadata: languageName: unknown linkType: soft -"@guardian/interfaces@2.17.0-prerelease, @guardian/interfaces@^2.17.0-prerelease, @guardian/interfaces@workspace:interfaces": +"@guardian/interfaces@2.17.0, @guardian/interfaces@^2.17.0, @guardian/interfaces@workspace:interfaces": version: 0.0.0-use.local resolution: "@guardian/interfaces@workspace:interfaces" dependencies: @@ -3437,8 +3437,8 @@ __metadata: version: 0.0.0-use.local resolution: "analytics-service@workspace:analytics-service" dependencies: - "@guardian/common": ^2.17.0-prerelease - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 + "@guardian/interfaces": ^2.17.0 "@nestjs/common": ^9.4.1 "@nestjs/core": ^9.4.1 "@nestjs/jwt": ^10.0.3 @@ -3639,8 +3639,8 @@ __metadata: version: 0.0.0-use.local resolution: "api-gateway@workspace:api-gateway" dependencies: - "@guardian/common": ^2.17.0-prerelease - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 + "@guardian/interfaces": ^2.17.0 "@nestjs/common": ^9.4.1 "@nestjs/core": ^9.4.1 "@nestjs/jwt": ^10.0.3 @@ -4084,8 +4084,8 @@ __metadata: version: 0.0.0-use.local resolution: "auth-service@workspace:auth-service" dependencies: - "@guardian/common": ^2.17.0-prerelease - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 + "@guardian/interfaces": ^2.17.0 "@meeco/cryppo": ^2.0.2 "@mikro-orm/core": 5.7.12 "@mikro-orm/mongodb": 5.7.12 @@ -7590,8 +7590,8 @@ __metadata: version: 0.0.0-use.local resolution: "guardian-service@workspace:guardian-service" dependencies: - "@guardian/common": ^2.17.0-prerelease - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 + "@guardian/interfaces": ^2.17.0 "@hashgraph/sdk": 2.24.2 "@mattrglobal/jsonld-signatures-bbs": ^1.1.2 "@meeco/cryppo": ^2.0.2 @@ -10141,8 +10141,8 @@ __metadata: version: 0.0.0-use.local resolution: "logger-service@workspace:logger-service" dependencies: - "@guardian/common": ^2.17.0-prerelease - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 + "@guardian/interfaces": ^2.17.0 "@mikro-orm/core": 5.7.12 "@mikro-orm/mongodb": 5.7.12 "@nestjs/common": ^9.4.1 @@ -10935,7 +10935,7 @@ __metadata: version: 0.0.0-use.local resolution: "mrv-sender@workspace:mrv-sender" dependencies: - "@guardian/common": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 "@transmute/credentials-context": 0.7.0-unstable.80 "@transmute/did-context": 0.7.0-unstable.80 "@transmute/ed25519-signature-2018": 0.7.0-unstable.80 @@ -11486,8 +11486,8 @@ __metadata: version: 0.0.0-use.local resolution: "notification-service@workspace:notification-service" dependencies: - "@guardian/common": ^2.17.0-prerelease - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 + "@guardian/interfaces": ^2.17.0 "@mikro-orm/core": 5.7.12 "@mikro-orm/mongodb": 5.7.12 "@nestjs/common": ^9.4.1 @@ -12252,8 +12252,8 @@ __metadata: version: 0.0.0-use.local resolution: "policy-service@workspace:policy-service" dependencies: - "@guardian/common": 2.17.0-prerelease - "@guardian/interfaces": 2.17.0-prerelease + "@guardian/common": 2.17.0 + "@guardian/interfaces": 2.17.0 "@hashgraph/sdk": 2.24.2 "@mattrglobal/jsonld-signatures-bbs": ^1.1.2 "@meeco/cryppo": 2.0.2 @@ -15500,8 +15500,8 @@ __metadata: version: 0.0.0-use.local resolution: "worker-service@workspace:worker-service" dependencies: - "@guardian/common": ^2.17.0-prerelease - "@guardian/interfaces": ^2.17.0-prerelease + "@guardian/common": ^2.17.0 + "@guardian/interfaces": ^2.17.0 "@hashgraph/sdk": 2.24.2 "@nestjs/common": ^9.4.1 "@nestjs/core": ^9.4.1