diff --git a/.dev/appsettings.override.json b/.dev/appsettings.override.json index 52c00c70..2af4057d 100644 --- a/.dev/appsettings.override.json +++ b/.dev/appsettings.override.json @@ -64,7 +64,8 @@ } }, "Application": { - "didDomainName": "localhost" + "didDomainName": "localhost", + "maxNumberOfMessageRecipients": 5 } }, "Files": { diff --git a/.dev/compose.backbone.env b/.dev/compose.backbone.env index eedce13f..c74ce6ea 100644 --- a/.dev/compose.backbone.env +++ b/.dev/compose.backbone.env @@ -1 +1 @@ -BACKBONE_VERSION=6.28.0 +BACKBONE_VERSION=6.30.0 diff --git a/.dev/compose.backbone.yml b/.dev/compose.backbone.yml index c39a6bff..48fe7a48 100644 --- a/.dev/compose.backbone.yml +++ b/.dev/compose.backbone.yml @@ -89,7 +89,7 @@ services: rabbitmq: container_name: bkb-rabbitmq hostname: rabbitmq - image: rabbitmq:3.12.10-management-alpine + image: rabbitmq:4.0.5-alpine ### seeds ### diff --git a/package-lock.json b/package-lock.json index 356a5056..1ef40bba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@js-soft/docdb-access-mongo": "1.2.0", "@js-soft/node-logger": "1.2.0", "@js-soft/ts-utils": "^2.3.3", - "@nmshd/runtime": "6.23.1", + "@nmshd/runtime": "6.24.2", "@nmshd/typescript-ioc": "^3.2.4", "@nmshd/typescript-rest": "^3.1.0", "agentkeepalive": "4.6.0", @@ -46,8 +46,8 @@ "@js-soft/eslint-config-ts": "1.6.13", "@js-soft/license-check": "1.0.9", "@nmshd/connector-sdk": "*", - "@nmshd/content": "6.23.1", - "@nmshd/core-types": "6.23.1", + "@nmshd/content": "6.24.2", + "@nmshd/core-types": "6.24.2", "@nmshd/typescript-rest-swagger": "^1.4.1", "@types/amqplib": "^0.10.6", "@types/compression": "^1.7.5", @@ -1729,39 +1729,39 @@ "link": true }, "node_modules/@nmshd/consumption": { - "version": "6.23.1", - "resolved": "https://registry.npmjs.org/@nmshd/consumption/-/consumption-6.23.1.tgz", - "integrity": "sha512-1XWsDi2TVG1nSgmRr6AMzlt9UzJ6/yv62JIbF+ndfWpd0r0ae8mJ1E6WlKWJ8Cca15xEANmbJL1Y+B4Kq7oAbg==", + "version": "6.24.2", + "resolved": "https://registry.npmjs.org/@nmshd/consumption/-/consumption-6.24.2.tgz", + "integrity": "sha512-807ymQ29u7hGpcIZf1wJ4cs5/JUZtNoLxQvoxRNfah98jxj3A1OAd3YrwY8/tntr5crBv4bQcKcHZ3AFCh52Pw==", "license": "MIT", "dependencies": { "@js-soft/docdb-querytranslator": "^1.1.5", "@js-soft/ts-serval": "2.0.11", "@js-soft/ts-utils": "2.3.3", - "@nmshd/content": "6.23.1", - "@nmshd/core-types": "6.23.1", + "@nmshd/content": "6.24.2", + "@nmshd/core-types": "6.24.2", "@nmshd/iql": "^1.0.2", - "@nmshd/transport": "6.23.1", + "@nmshd/transport": "6.24.2", "lodash": "^4.17.21", "ts-simple-nameof": "^1.3.1" } }, "node_modules/@nmshd/content": { - "version": "6.23.1", - "resolved": "https://registry.npmjs.org/@nmshd/content/-/content-6.23.1.tgz", - "integrity": "sha512-dZPgf9ZYc3iMq2+EwzPneMeuevI2I/ZaCgACzbbcQYeV8DcwAV6aa4AzeekhriIULSRUFBghtCHP4wxEJZWvyg==", + "version": "6.24.2", + "resolved": "https://registry.npmjs.org/@nmshd/content/-/content-6.24.2.tgz", + "integrity": "sha512-30C6tCLxC8vhM96vQRUvCIpi945i2zsFZLpN8uuo+vj4iFIhQPOsn+1LlzqdjH8Dc1diEd1F4nhtwdvse3kZzQ==", "license": "MIT", "dependencies": { "@js-soft/ts-serval": "2.0.11", - "@nmshd/core-types": "6.23.1", + "@nmshd/core-types": "6.24.2", "@nmshd/iql": "^1.0.2", "luxon": "^3.5.0", "ts-simple-nameof": "^1.3.1" } }, "node_modules/@nmshd/core-types": { - "version": "6.23.1", - "resolved": "https://registry.npmjs.org/@nmshd/core-types/-/core-types-6.23.1.tgz", - "integrity": "sha512-ZagYQKvHbcEby2TF1kA0luESodrSO2FGCDQzp+XPjuCBkxPqNhKwleAo7bwOgP9PaJ7Qi9MajrkKcbRPBdGsYw==", + "version": "6.24.2", + "resolved": "https://registry.npmjs.org/@nmshd/core-types/-/core-types-6.24.2.tgz", + "integrity": "sha512-cvUqVmDXKlkmOnbOAtDxGw8Vu5y3WqO+J+LicIg95U57NZ27voSOUV8d4eV4jpit+jE77w1XRWKXRtsnU50VBA==", "license": "MIT", "dependencies": { "@js-soft/logging-abstractions": "^1.0.1", @@ -1787,21 +1787,21 @@ "license": "MIT" }, "node_modules/@nmshd/runtime": { - "version": "6.23.1", - "resolved": "https://registry.npmjs.org/@nmshd/runtime/-/runtime-6.23.1.tgz", - "integrity": "sha512-jcdmtD1g5Bn1johKnHBXx9/o+yfx2P+xyDi9huiZSrHoK5hLgetjcHkQ5IOo4K2jVLkxS7fh0Vk9TPue8imocA==", + "version": "6.24.2", + "resolved": "https://registry.npmjs.org/@nmshd/runtime/-/runtime-6.24.2.tgz", + "integrity": "sha512-ZCG7MKMyxioKU4hnmgYZ8B2bDgu8zK9d9fnOYUODwbPA6cwyUlvKdOyC9ZtdgEisQXZuFXkiNY5zd8ZDHT0Veg==", "license": "MIT", "dependencies": { "@js-soft/docdb-querytranslator": "^1.1.5", "@js-soft/logging-abstractions": "^1.0.1", "@js-soft/ts-serval": "2.0.11", "@js-soft/ts-utils": "^2.3.3", - "@nmshd/consumption": "6.23.1", - "@nmshd/content": "6.23.1", - "@nmshd/core-types": "6.23.1", + "@nmshd/consumption": "6.24.2", + "@nmshd/content": "6.24.2", + "@nmshd/core-types": "6.24.2", "@nmshd/crypto": "2.1.0", "@nmshd/iql": "^1.0.2", - "@nmshd/transport": "6.23.1", + "@nmshd/transport": "6.24.2", "@nmshd/typescript-ioc": "3.2.4", "ajv": "^8.17.1", "ajv-errors": "^3.0.0", @@ -1815,16 +1815,16 @@ } }, "node_modules/@nmshd/transport": { - "version": "6.23.1", - "resolved": "https://registry.npmjs.org/@nmshd/transport/-/transport-6.23.1.tgz", - "integrity": "sha512-YpEhavU5Wq7zdmrvW9W5bXYhSwgBvbnZiK0GxNm87+YfCpv2n6U+WJURr6FElfnI6LCrLr2BI0ZRlSEKRcz4Lg==", + "version": "6.24.2", + "resolved": "https://registry.npmjs.org/@nmshd/transport/-/transport-6.24.2.tgz", + "integrity": "sha512-IDD/dygc4CLy1hGSFYz3Oc/TioXA3JkVUT2F4e94gFE6zR6Dnq0ocOXQF5RO/D4zH5qRfTnMhTVj+1i1bLDoUg==", "license": "MIT", "dependencies": { - "@js-soft/docdb-access-abstractions": "1.0.4", + "@js-soft/docdb-access-abstractions": "1.1.0", "@js-soft/logging-abstractions": "^1.0.1", "@js-soft/simple-logger": "1.0.5", "@js-soft/ts-utils": "^2.3.3", - "@nmshd/core-types": "6.23.1", + "@nmshd/core-types": "6.24.2", "@nmshd/crypto": "2.1.0", "axios": "^1.7.9", "fast-json-patch": "^3.1.1", @@ -1833,18 +1833,12 @@ "json-stringify-safe": "^5.0.1", "lodash": "^4.17.21", "luxon": "^3.5.0", - "qs": "^6.13.1", + "qs": "^6.14.0", "reflect-metadata": "^0.2.2", "ts-simple-nameof": "^1.3.1", "uuid": "^11.0.5" } }, - "node_modules/@nmshd/transport/node_modules/@js-soft/docdb-access-abstractions": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@js-soft/docdb-access-abstractions/-/docdb-access-abstractions-1.0.4.tgz", - "integrity": "sha512-pz5/K/C3e74qzlYRQcv3DY2P854OOSumyVzwZ4GzYV5Wd9QjWdxtn9TWp10WLNi+Y1eWQPNB3LiLuVch4rBROQ==", - "license": "MIT" - }, "node_modules/@nmshd/transport/node_modules/uuid": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz", @@ -13943,7 +13937,7 @@ "name": "@nmshd/connector-sdk", "license": "MIT", "dependencies": { - "@nmshd/content": "6.23.1", + "@nmshd/content": "6.24.2", "axios": "^1.7.9", "form-data": "^4.0.1", "qs": "^6.14.0" diff --git a/package.json b/package.json index a7fc5a62..28a5b26b 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "@js-soft/docdb-access-mongo": "1.2.0", "@js-soft/node-logger": "1.2.0", "@js-soft/ts-utils": "^2.3.3", - "@nmshd/runtime": "6.23.1", + "@nmshd/runtime": "6.24.2", "@nmshd/typescript-ioc": "^3.2.4", "@nmshd/typescript-rest": "^3.1.0", "agentkeepalive": "4.6.0", @@ -113,8 +113,8 @@ "@js-soft/eslint-config-ts": "1.6.13", "@js-soft/license-check": "1.0.9", "@nmshd/connector-sdk": "*", - "@nmshd/content": "6.23.1", - "@nmshd/core-types": "6.23.1", + "@nmshd/content": "6.24.2", + "@nmshd/core-types": "6.24.2", "@nmshd/typescript-rest-swagger": "^1.4.1", "@types/amqplib": "^0.10.6", "@types/compression": "^1.7.5", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 6f6712b3..2c8a91cb 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -30,7 +30,7 @@ "build:schemas:watch": "npx nodemon -e ts -w 'src/types' --exec 'npm run build:schemas'" }, "dependencies": { - "@nmshd/content": "6.23.1", + "@nmshd/content": "6.24.2", "axios": "^1.7.9", "form-data": "^4.0.1", "qs": "^6.14.0" diff --git a/packages/sdk/src/endpoints/AttributesEndpoint.ts b/packages/sdk/src/endpoints/AttributesEndpoint.ts index 1d2c3dae..d1593d95 100644 --- a/packages/sdk/src/endpoints/AttributesEndpoint.ts +++ b/packages/sdk/src/endpoints/AttributesEndpoint.ts @@ -1,4 +1,6 @@ import { + CanCreateRepositoryAttributeRequest, + CanCreateRepositoryAttributeResponse, ConnectorAttribute, ConnectorAttributeTagCollection, ConnectorAttributes, @@ -25,6 +27,10 @@ import { import { Endpoint } from "./Endpoint"; export class AttributesEndpoint extends Endpoint { + public async canCreateRepositoryAttribute(request: CanCreateRepositoryAttributeRequest): Promise> { + return await this.put("/api/v2/Attributes/CanCreate", request); + } + public async createRepositoryAttribute(request: CreateRepositoryAttributeRequest): Promise> { return await this.post("/api/v2/Attributes", request); } diff --git a/packages/sdk/src/types/attributes/index.ts b/packages/sdk/src/types/attributes/index.ts index 3a0301d3..3f1ff398 100644 --- a/packages/sdk/src/types/attributes/index.ts +++ b/packages/sdk/src/types/attributes/index.ts @@ -4,6 +4,8 @@ export * from "./ConnectorAttributeTagCollection"; export * from "./IdentityAttributeQuery"; export * from "./IQLQuery"; export * from "./RelationshipAttributeQuery"; +export * from "./requests/CanCreateRepositoryAttributeRequest"; +export * from "./requests/CanCreateRepositoryAttributeResponse"; export * from "./requests/CreateRepositoryAttributeRequest"; export * from "./requests/DeleteOwnSharedAttributeAndNotifyPeerResponse"; export * from "./requests/DeletePeerSharedAttributeAndNotifyOwnerResponse"; diff --git a/packages/sdk/src/types/attributes/requests/CanCreateRepositoryAttributeRequest.ts b/packages/sdk/src/types/attributes/requests/CanCreateRepositoryAttributeRequest.ts new file mode 100644 index 00000000..af4eb496 --- /dev/null +++ b/packages/sdk/src/types/attributes/requests/CanCreateRepositoryAttributeRequest.ts @@ -0,0 +1,10 @@ +import { AttributeValues } from "@nmshd/content"; + +export interface CanCreateRepositoryAttributeRequest { + content: { + value: AttributeValues.Identity.Json; + tags?: string[]; + validFrom?: string; + validTo?: string; + }; +} diff --git a/packages/sdk/src/types/attributes/requests/CanCreateRepositoryAttributeResponse.ts b/packages/sdk/src/types/attributes/requests/CanCreateRepositoryAttributeResponse.ts new file mode 100644 index 00000000..1f6e3b2d --- /dev/null +++ b/packages/sdk/src/types/attributes/requests/CanCreateRepositoryAttributeResponse.ts @@ -0,0 +1,7 @@ +export type CanCreateRepositoryAttributeResponse = + | { isSuccess: true } + | { + isSuccess: false; + code: string; + message: string; + }; diff --git a/src/modules/coreHttpApi/controllers/AttributesController.ts b/src/modules/coreHttpApi/controllers/AttributesController.ts index b364d91d..058ce8cf 100644 --- a/src/modules/coreHttpApi/controllers/AttributesController.ts +++ b/src/modules/coreHttpApi/controllers/AttributesController.ts @@ -1,6 +1,6 @@ import { ConsumptionServices, RuntimeErrors, TransportServices } from "@nmshd/runtime"; import { Inject } from "@nmshd/typescript-ioc"; -import { Accept, Context, DELETE, GET, POST, Path, PathParam, QueryParam, Return, ServiceContext } from "@nmshd/typescript-rest"; +import { Accept, Context, DELETE, GET, POST, PUT, Path, PathParam, QueryParam, Return, ServiceContext } from "@nmshd/typescript-rest"; import { Envelope } from "../../../infrastructure"; import { BaseController } from "../common/BaseController"; @@ -13,6 +13,14 @@ export class AttributesController extends BaseController { super(); } + @PUT + @Path("CanCreate") + @Accept("application/json") + public async canCreateRepositoryAttribute(request: any): Promise { + const result = await this.consumptionServices.attributes.canCreateRepositoryAttribute(request); + return this.ok(result); + } + @POST @Accept("application/json") public async createRepositoryAttribute(request: any): Promise> { diff --git a/src/modules/coreHttpApi/openapi.yml b/src/modules/coreHttpApi/openapi.yml index ed6533b4..76d924d3 100644 --- a/src/modules/coreHttpApi/openapi.yml +++ b/src/modules/coreHttpApi/openapi.yml @@ -257,6 +257,57 @@ paths: # ------------------- Attributes ------------------- + /api/v2/Attributes/CanCreate: + put: + operationId: canCreateRepositoryAttribute + description: "Checks if a Repository Attribute can be created with the given parameters." + tags: + - Attributes + requestBody: + content: + application/json: + schema: + additionalProperties: false + properties: + content: + type: object + additionalProperties: false + required: + - value + properties: + value: + $ref: "#/components/schemas/AttributeValue" + tags: + $ref: "#/components/schemas/IdentityAttributeContent_tags" + validFrom: + $ref: "#/components/schemas/AttributeContent_validFrom" + validTo: + $ref: "#/components/schemas/AttributeContent_validTo" + responses: + 200: + description: Success + content: + application/json: + schema: + type: object + properties: + result: + nullable: false + $ref: "#/components/schemas/CanCreateRepositoryAttributeResponse" + required: + - result + headers: + X-Response-Duration-ms: + schema: + $ref: "#/components/schemas/HeaderContent_X-Response-Duration-ms" + X-Response-Time: + schema: + $ref: "#/components/schemas/HeaderContent_X-Response-Time" + 401: + $ref: "#/components/responses/Unauthorized" + 403: + $ref: "#/components/responses/Forbidden" + /api/v2/Attributes: post: operationId: createRepositoryAttribute @@ -5049,6 +5100,32 @@ components: required: - displayNames + CanCreateRepositoryAttributeResponse: + type: object + properties: + isSuccess: + type: boolean + oneOf: + - properties: + isSuccess: + const: true + required: + - isSuccess + additionalProperties: false + + - properties: + isSuccess: + const: false + code: + type: string + message: + type: string + required: + - isSuccess + - code + - message + additionalProperties: false + ConnectorHealth: type: object properties: diff --git a/test/attributes.test.ts b/test/attributes.test.ts index 5fbaf228..ed8a0803 100644 --- a/test/attributes.test.ts +++ b/test/attributes.test.ts @@ -40,6 +40,20 @@ beforeEach(async () => { }); describe("Attributes", () => { + test("should check if a repository attribute can be created", async () => { + const canCreateAttributeResponse = await client1.attributes.canCreateRepositoryAttribute({ + content: { + value: { + "@type": "GivenName", + value: "AGivenName" + }, + tags: ["content:edu.de"] + } + }); + + expect(canCreateAttributeResponse.result.isSuccess).toBe(true); + }); + test("should create a repository attribute", async () => { const createAttributeResponse = await client1.attributes.createRepositoryAttribute({ content: {