@twin.org/federated-catalogue-service 0.0.1-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +21 -0
  3. package/dist/cjs/index.cjs +2122 -0
  4. package/dist/esm/index.mjs +2104 -0
  5. package/dist/types/entities/dataResourceEntry.d.ts +59 -0
  6. package/dist/types/entities/dataSpaceConnectorEntry.d.ts +66 -0
  7. package/dist/types/entities/participantEntry.d.ts +42 -0
  8. package/dist/types/entities/serviceOfferingEntry.d.ts +55 -0
  9. package/dist/types/federatedCatalogueRoutes.d.ts +113 -0
  10. package/dist/types/federatedCatalogueService.d.ts +142 -0
  11. package/dist/types/index.d.ts +10 -0
  12. package/dist/types/models/IFederatedCatalogueServiceConfig.d.ts +15 -0
  13. package/dist/types/models/IFederatedCatalogueServiceConstructorOptions.d.ts +38 -0
  14. package/dist/types/restEntryPoints.d.ts +2 -0
  15. package/dist/types/schema.d.ts +4 -0
  16. package/dist/types/verification/complianceCredentialVerificationService.d.ts +32 -0
  17. package/docs/changelog.md +143 -0
  18. package/docs/examples.md +1 -0
  19. package/docs/open-api/spec.json +3434 -0
  20. package/docs/reference/classes/DataResourceEntry.md +118 -0
  21. package/docs/reference/classes/DataSpaceConnectorEntry.md +133 -0
  22. package/docs/reference/classes/FederatedCatalogueService.md +389 -0
  23. package/docs/reference/classes/ParticipantEntry.md +85 -0
  24. package/docs/reference/classes/ServiceOfferingEntry.md +109 -0
  25. package/docs/reference/functions/complianceCredentialPresentation.md +37 -0
  26. package/docs/reference/functions/dataResourceCredentialPresentation.md +37 -0
  27. package/docs/reference/functions/dataResourceGet.md +31 -0
  28. package/docs/reference/functions/dataResourceList.md +31 -0
  29. package/docs/reference/functions/dataSpaceConnectorCredentialPresentation.md +37 -0
  30. package/docs/reference/functions/dataSpaceConnectorGet.md +31 -0
  31. package/docs/reference/functions/dataSpaceConnectorList.md +31 -0
  32. package/docs/reference/functions/generateRestRoutesFederatedCatalogue.md +25 -0
  33. package/docs/reference/functions/initSchema.md +9 -0
  34. package/docs/reference/functions/participantGet.md +31 -0
  35. package/docs/reference/functions/participantList.md +31 -0
  36. package/docs/reference/functions/serviceOfferingCredentialPresentation.md +37 -0
  37. package/docs/reference/functions/serviceOfferingGet.md +31 -0
  38. package/docs/reference/functions/serviceOfferingList.md +31 -0
  39. package/docs/reference/index.md +36 -0
  40. package/docs/reference/interfaces/IFederatedCatalogueServiceConfig.md +21 -0
  41. package/docs/reference/interfaces/IFederatedCatalogueServiceConstructorOptions.md +83 -0
  42. package/docs/reference/variables/restEntryPoints.md +3 -0
  43. package/docs/reference/variables/tagsFederatedCatalogue.md +5 -0
  44. package/locales/en.json +21 -0
  45. package/package.json +52 -0
@@ -0,0 +1,2122 @@
1
+ 'use strict';
2
+
3
+ var core = require('@twin.org/core');
4
+ var federatedCatalogueModels = require('@twin.org/federated-catalogue-models');
5
+ var standardsGaiaX = require('@twin.org/standards-gaia-x');
6
+ var standardsSchemaOrg = require('@twin.org/standards-schema-org');
7
+ var web = require('@twin.org/web');
8
+ var dataJsonLd = require('@twin.org/data-json-ld');
9
+ var entity = require('@twin.org/entity');
10
+ var entityStorageModels = require('@twin.org/entity-storage-models');
11
+ var identityModels = require('@twin.org/identity-models');
12
+ var loggingModels = require('@twin.org/logging-models');
13
+ var crypto = require('@twin.org/crypto');
14
+ var standardsW3cDid = require('@twin.org/standards-w3c-did');
15
+
16
+ /**
17
+ * The source used when communicating about these routes.
18
+ */
19
+ const ROUTES_SOURCE = "federatedCatalogueRoutes";
20
+ /**
21
+ * Participants route.
22
+ */
23
+ const PARTICIPANTS_ROUTE = "participants";
24
+ /**
25
+ * Service offering route.
26
+ */
27
+ const SERVICE_OFFERING_ROUTE = "service-offerings";
28
+ /**
29
+ * Data Resource route.
30
+ */
31
+ const DATA_RESOURCE_ROUTE = "data-resources";
32
+ /**
33
+ * Data Space Connector route.
34
+ */
35
+ const DATA_SPACE_CONNECTOR_ROUTE = "data-space-connectors";
36
+ /**
37
+ * The tag to associate with the routes.
38
+ */
39
+ const tagsFederatedCatalogue = [
40
+ {
41
+ name: "Federated Catalogue",
42
+ description: "Endpoints to access a Federated Catalogue."
43
+ }
44
+ ];
45
+ /**
46
+ * The REST routes for Federated Catalogue.
47
+ * @param baseRouteName Prefix to prepend to the paths.
48
+ * @param factoryServiceName The name of the service to use in the routes store in the ServiceFactory.
49
+ * @returns The generated routes.
50
+ */
51
+ function generateRestRoutesFederatedCatalogue(baseRouteName, factoryServiceName) {
52
+ const createParticipantRoute = {
53
+ operationId: "compliancePresentationRequest",
54
+ summary: "Present a Compliance Credential",
55
+ tag: tagsFederatedCatalogue[0].name,
56
+ method: "POST",
57
+ path: `${baseRouteName}/participant-credentials`,
58
+ handler: async (httpRequestContext, request) => complianceCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request),
59
+ requestType: {
60
+ mimeType: web.MimeTypes.Jwt,
61
+ type: "ICompliancePresentationRequest",
62
+ examples: [
63
+ {
64
+ id: "compliancePresentationRequestExample",
65
+ request: {
66
+ body: "ey..."
67
+ }
68
+ }
69
+ ]
70
+ },
71
+ responseType: [
72
+ {
73
+ type: "ICreatedResponse"
74
+ },
75
+ { type: "IUnprocessableEntityResponse" }
76
+ ]
77
+ };
78
+ const createServiceOfferingRoute = {
79
+ operationId: "serviceOfferingPresentationRequest",
80
+ summary: "Present a Service Offering Credential",
81
+ tag: tagsFederatedCatalogue[0].name,
82
+ method: "POST",
83
+ path: `${baseRouteName}/service-offering-credentials`,
84
+ handler: async (httpRequestContext, request) => serviceOfferingCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request),
85
+ requestType: {
86
+ mimeType: web.MimeTypes.Jwt,
87
+ type: "ICompliancePresentationRequest",
88
+ examples: [
89
+ {
90
+ id: "serviceOfferingPresentationRequestExample",
91
+ request: {
92
+ body: "ey..."
93
+ }
94
+ }
95
+ ]
96
+ },
97
+ responseType: [
98
+ {
99
+ type: "ICreatedResponse"
100
+ },
101
+ { type: "IUnprocessableEntityResponse" }
102
+ ]
103
+ };
104
+ const createDataSpaceConnectorRoute = {
105
+ operationId: "dataSpaceConnectorPresentationRequest",
106
+ summary: "Present a Data Space Connector Credential",
107
+ tag: tagsFederatedCatalogue[0].name,
108
+ method: "POST",
109
+ path: `${baseRouteName}/data-space-connector-credentials`,
110
+ handler: async (httpRequestContext, request) => dataSpaceConnectorCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request),
111
+ requestType: {
112
+ mimeType: web.MimeTypes.Jwt,
113
+ type: "ICompliancePresentationRequest",
114
+ examples: [
115
+ {
116
+ id: "dataSpaceConnectorPresentationRequestExample",
117
+ request: {
118
+ body: "ey..."
119
+ }
120
+ }
121
+ ]
122
+ },
123
+ responseType: [
124
+ {
125
+ type: "ICreatedResponse"
126
+ },
127
+ { type: "IUnprocessableEntityResponse" }
128
+ ]
129
+ };
130
+ const createDataResourceRoute = {
131
+ operationId: "dataResourcePresentationRequest",
132
+ summary: "Present a Data Resource Credential",
133
+ tag: tagsFederatedCatalogue[0].name,
134
+ method: "POST",
135
+ path: `${baseRouteName}/data-resource-credentials`,
136
+ handler: async (httpRequestContext, request) => dataResourceCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request),
137
+ requestType: {
138
+ mimeType: web.MimeTypes.Jwt,
139
+ type: "ICompliancePresentationRequest",
140
+ examples: [
141
+ {
142
+ id: "dataResourcePresentationRequestExample",
143
+ request: {
144
+ body: "ey..."
145
+ }
146
+ }
147
+ ]
148
+ },
149
+ responseType: [
150
+ {
151
+ type: "ICreatedResponse"
152
+ },
153
+ { type: "IUnprocessableEntityResponse" }
154
+ ]
155
+ };
156
+ const participantEntryExample = {
157
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
158
+ id: "did:iota:xxx",
159
+ type: standardsGaiaX.GaiaXTypes.Participant,
160
+ registrationNumber: {
161
+ type: standardsGaiaX.GaiaXTypes.LocalRegistrationNumber,
162
+ local: "P1234567"
163
+ },
164
+ legalName: "A Inc.",
165
+ issuer: "did:iota:zzz",
166
+ legalAddress: {
167
+ type: standardsGaiaX.GaiaXTypes.Address,
168
+ countryCode: "KE"
169
+ },
170
+ validFrom: "2024-08-01T12:00:00Z",
171
+ validUntil: "2025-08-01T12:00:00Z",
172
+ dateCreated: "2024-08-02T13:45:00Z",
173
+ evidence: ["https://credentials.example.org/1234567"]
174
+ };
175
+ const listParticipantsRoute = {
176
+ operationId: "federatedCatalogueListParticipants",
177
+ summary: "Get a list of the participant entries",
178
+ tag: tagsFederatedCatalogue[0].name,
179
+ method: "GET",
180
+ path: `${baseRouteName}/${PARTICIPANTS_ROUTE}`,
181
+ handler: async (httpRequestContext, request) => participantList(httpRequestContext, factoryServiceName, request),
182
+ requestType: {
183
+ type: "IParticipantListRequest",
184
+ examples: [
185
+ {
186
+ id: "participantListRequestExample",
187
+ request: {
188
+ query: {
189
+ registrationNumber: "abc"
190
+ }
191
+ }
192
+ }
193
+ ]
194
+ },
195
+ responseType: [
196
+ {
197
+ type: "IParticipantListResponse",
198
+ examples: [
199
+ {
200
+ id: "participantListResponseExample",
201
+ response: {
202
+ body: {
203
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
204
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
205
+ itemListElement: [participantEntryExample]
206
+ }
207
+ }
208
+ }
209
+ ]
210
+ }
211
+ ]
212
+ };
213
+ const getParticipantRoute = {
214
+ operationId: "federatedCatalogueGetParticipant",
215
+ summary: "Get a participant",
216
+ tag: tagsFederatedCatalogue[0].name,
217
+ method: "GET",
218
+ path: `${baseRouteName}/${PARTICIPANTS_ROUTE}/:id`,
219
+ handler: async (httpRequestContext, request) => participantGet(httpRequestContext, factoryServiceName, request),
220
+ requestType: {
221
+ type: "ICatalogueEntryGetRequest",
222
+ examples: [
223
+ {
224
+ id: "participantGetRequestExample",
225
+ request: {
226
+ pathParams: {
227
+ id: "did:iota:123456"
228
+ }
229
+ }
230
+ }
231
+ ]
232
+ },
233
+ responseType: [
234
+ {
235
+ type: "IParticipantGetResponse",
236
+ examples: [
237
+ {
238
+ id: "participantGetResponseExample",
239
+ response: {
240
+ body: participantEntryExample
241
+ }
242
+ }
243
+ ]
244
+ }
245
+ ]
246
+ };
247
+ const servicePolicyExample = {
248
+ "@context": [
249
+ "https://www.w3.org/ns/odrl/2/",
250
+ {
251
+ twin: "https://schema.twindev.org/odrl/",
252
+ jsonPathSelector: "twin:jsonPathSelector"
253
+ }
254
+ ],
255
+ "@type": "Agreement",
256
+ uid: "http://example.com/policy:1010",
257
+ assigner: "did:iota:testnet:0x1a7bded4d22dc54722435d624e4323e10fcbc570cd57462eabbf3a5ab2ced24f",
258
+ assignee: "did:iota:testnet:0x119adb64d01d3b0fa0d308c67db90ab1c6e0df6aebe5b7e0250783f57cd10c21",
259
+ permission: [
260
+ {
261
+ target: {
262
+ type: "https://vocabulary.uncefact.org/Document",
263
+ refinement: {
264
+ leftOperand: {
265
+ "@id": "https://w3id.org/twin/odrl/propertyValue",
266
+ jsonPathSelector: ".documentTypeCode"
267
+ },
268
+ operator: "eq",
269
+ rightOperand: "https://vocabulary.uncefact.org/DocumentCodeList#331"
270
+ }
271
+ },
272
+ action: "extract"
273
+ }
274
+ ]
275
+ };
276
+ const serviceOfferingEntryExample = {
277
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
278
+ id: "http://example.org/is123456",
279
+ name: "Service 1",
280
+ type: standardsGaiaX.GaiaXTypes.ServiceOffering,
281
+ servicePolicy: [servicePolicyExample],
282
+ endpoint: {
283
+ type: standardsGaiaX.GaiaXTypes.Endpoint,
284
+ endpointURL: "https://endpoint.example.org/api"
285
+ },
286
+ issuer: "did:iota:7890",
287
+ providedBy: "did:iota:1234567",
288
+ validFrom: "2024-08-01T12:00:00Z",
289
+ validUntil: "2025-08-01T12:00:00Z",
290
+ dateCreated: "2024-08-02T13:45:00Z",
291
+ evidence: ["https://credentials.example.org/1234567"]
292
+ };
293
+ const listServicesRoute = {
294
+ operationId: "federatedCatalogueListServices",
295
+ summary: "Get a list of the service entries",
296
+ tag: tagsFederatedCatalogue[0].name,
297
+ method: "GET",
298
+ path: `${baseRouteName}/${SERVICE_OFFERING_ROUTE}`,
299
+ handler: async (httpRequestContext, request) => serviceOfferingList(httpRequestContext, factoryServiceName, request),
300
+ requestType: {
301
+ type: "IServiceOfferingListRequest",
302
+ examples: [
303
+ {
304
+ id: "serviceOfferingListRequestExample",
305
+ request: {
306
+ query: {
307
+ providedBy: "did:iota:1234"
308
+ }
309
+ }
310
+ }
311
+ ]
312
+ },
313
+ responseType: [
314
+ {
315
+ type: "IServiceOfferingListResponse",
316
+ examples: [
317
+ {
318
+ id: "serviceOfferingListResponseExample",
319
+ response: {
320
+ body: {
321
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
322
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
323
+ itemListElement: [serviceOfferingEntryExample]
324
+ }
325
+ }
326
+ }
327
+ ]
328
+ }
329
+ ]
330
+ };
331
+ const getServiceRoute = {
332
+ operationId: "federatedCatalogueGetService",
333
+ summary: "Get a Service Offering entry",
334
+ tag: tagsFederatedCatalogue[0].name,
335
+ method: "GET",
336
+ path: `${baseRouteName}/${SERVICE_OFFERING_ROUTE}/:id`,
337
+ handler: async (httpRequestContext, request) => serviceOfferingGet(httpRequestContext, factoryServiceName, request),
338
+ requestType: {
339
+ type: "ICatalogueEntryGetRequest",
340
+ examples: [
341
+ {
342
+ id: "serviceOfferingGetRequestExample",
343
+ request: {
344
+ pathParams: {
345
+ id: "https://my-services.example.org/service1"
346
+ }
347
+ }
348
+ }
349
+ ]
350
+ },
351
+ responseType: [
352
+ {
353
+ type: "IServiceOfferingGetResponse",
354
+ examples: [
355
+ {
356
+ id: "serviceOfferingGetResponseExample",
357
+ response: {
358
+ body: serviceOfferingEntryExample
359
+ }
360
+ }
361
+ ]
362
+ }
363
+ ]
364
+ };
365
+ const resourcePolicyExample = {
366
+ "@context": "https://www.w3.org/ns/odrl/2/",
367
+ "@type": "Offer",
368
+ uid: "http://example.com/policy:1010",
369
+ assigner: "did:iota:testnet:0x1a7bded4d22dc54722435d624e4323e10fcbc570cd57462eabbf3a5ab2ced24f",
370
+ permission: [
371
+ {
372
+ target: {
373
+ type: "https://vocabulary.uncefact.org/Document"
374
+ },
375
+ action: "extract"
376
+ }
377
+ ]
378
+ };
379
+ const dataResourceEntryExample = {
380
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
381
+ id: "http://example.org/is123456",
382
+ name: "Data Resource 1",
383
+ type: "DataResource",
384
+ copyrightOwnedBy: "did:iota:1234",
385
+ license: "http://licenses.example.org/12345",
386
+ resourcePolicy: [resourcePolicyExample],
387
+ exposedThrough: "https://ds-connectors.example.org/ds1",
388
+ producedBy: "did:iota:1234567",
389
+ issuer: "did:iota:987654",
390
+ validFrom: "2024-08-01T12:00:00Z",
391
+ validUntil: "2025-08-01T12:00:00Z",
392
+ dateCreated: "2024-08-02T13:45:00Z",
393
+ evidence: ["https://credentials.example.org/1234567"]
394
+ };
395
+ const listDataResourcesRoute = {
396
+ operationId: "federatedCatalogueListResources",
397
+ summary: "Get a list of the data resource entries",
398
+ tag: tagsFederatedCatalogue[0].name,
399
+ method: "GET",
400
+ path: `${baseRouteName}/${DATA_RESOURCE_ROUTE}`,
401
+ handler: async (httpRequestContext, request) => dataResourceList(httpRequestContext, factoryServiceName, request),
402
+ requestType: {
403
+ type: "IDataResourceListRequest",
404
+ examples: [
405
+ {
406
+ id: "dataResourceListRequestExample",
407
+ request: {
408
+ query: {
409
+ producedBy: "did:iota:1234"
410
+ }
411
+ }
412
+ }
413
+ ]
414
+ },
415
+ responseType: [
416
+ {
417
+ type: "IDataResourceListResponse",
418
+ examples: [
419
+ {
420
+ id: "dataResourceListResponseExample",
421
+ response: {
422
+ body: {
423
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
424
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
425
+ itemListElement: [dataResourceEntryExample]
426
+ }
427
+ }
428
+ }
429
+ ]
430
+ }
431
+ ]
432
+ };
433
+ const getDataResourceRoute = {
434
+ operationId: "federatedCatalogueGetDataResource",
435
+ summary: "Get a Data Resource entry",
436
+ tag: tagsFederatedCatalogue[0].name,
437
+ method: "GET",
438
+ path: `${baseRouteName}/${DATA_RESOURCE_ROUTE}/:id`,
439
+ handler: async (httpRequestContext, request) => dataResourceGet(httpRequestContext, factoryServiceName, request),
440
+ requestType: {
441
+ type: "IDataResourceListRequest",
442
+ examples: [
443
+ {
444
+ id: "dataResourceListRequestExample",
445
+ request: {
446
+ pathParams: {
447
+ id: "https://data-resources.example.org/drs1"
448
+ }
449
+ }
450
+ }
451
+ ]
452
+ },
453
+ responseType: [
454
+ {
455
+ type: "IDataResourceGetResponse",
456
+ examples: [
457
+ {
458
+ id: "dataResourceGetResponseExample",
459
+ response: {
460
+ body: dataResourceEntryExample
461
+ }
462
+ }
463
+ ]
464
+ }
465
+ ]
466
+ };
467
+ const dataSpaceConnectorEntryExample = {
468
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
469
+ id: "https://my-ds-connectors.example.org/ds-connector-ABCD",
470
+ type: [standardsGaiaX.GaiaXTypes.DataExchangeComponent, federatedCatalogueModels.FederatedCatalogueTypes.DataSpaceConnector],
471
+ identity: "did:iota:testnet:123456",
472
+ defaultEndpoint: {
473
+ type: standardsGaiaX.GaiaXTypes.Endpoint,
474
+ endpointURL: "https://my-twin-node.example.org:9000/twin-ds-connector"
475
+ },
476
+ subscriptionActivityEndpoint: {
477
+ type: standardsGaiaX.GaiaXTypes.Endpoint,
478
+ endpointURL: "/subscriptions"
479
+ },
480
+ pushActivityEndpoint: {
481
+ type: standardsGaiaX.GaiaXTypes.Endpoint,
482
+ endpointURL: "/notify"
483
+ },
484
+ pullDataEndpoint: {
485
+ type: standardsGaiaX.GaiaXTypes.Endpoint,
486
+ endpointURL: "/data"
487
+ },
488
+ maintainer: "did:iota:99999",
489
+ offeredResource: ["https://my-data-resource.example.org"],
490
+ issuer: "did:iota:987654",
491
+ validFrom: "2024-08-01T12:00:00Z",
492
+ validUntil: "2025-08-01T12:00:00Z",
493
+ dateCreated: "2024-08-02T13:45:00Z",
494
+ evidence: ["https://credentials.example.org/1234567"]
495
+ };
496
+ const listDataSpaceConnectorsRoute = {
497
+ operationId: "federatedCatalogueListDataSpaceConnectors",
498
+ summary: "Get a list of the Data Space connectors entries",
499
+ tag: tagsFederatedCatalogue[0].name,
500
+ method: "GET",
501
+ path: `${baseRouteName}/${DATA_SPACE_CONNECTOR_ROUTE}`,
502
+ handler: async (httpRequestContext, request) => dataSpaceConnectorList(httpRequestContext, factoryServiceName, request),
503
+ requestType: {
504
+ type: "IDataSpaceConnectorListRequest",
505
+ examples: [
506
+ {
507
+ id: "dataSpaceConnectorListRequestExample",
508
+ request: {
509
+ query: {
510
+ maintainedBy: "did:iota:1234"
511
+ }
512
+ }
513
+ }
514
+ ]
515
+ },
516
+ responseType: [
517
+ {
518
+ type: "IDataSpaceConnectorListResponse",
519
+ examples: [
520
+ {
521
+ id: "dataSpaceConnectorListResponseExample",
522
+ response: {
523
+ body: {
524
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
525
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
526
+ itemListElement: [dataSpaceConnectorEntryExample]
527
+ }
528
+ }
529
+ }
530
+ ]
531
+ }
532
+ ]
533
+ };
534
+ const getDataSpaceConnectorRoute = {
535
+ operationId: "federatedCatalogueGetDataSpaceConnector",
536
+ summary: "Get a Data Space Connector entry",
537
+ tag: tagsFederatedCatalogue[0].name,
538
+ method: "GET",
539
+ path: `${baseRouteName}/${DATA_SPACE_CONNECTOR_ROUTE}/:id`,
540
+ handler: async (httpRequestContext, request) => dataSpaceConnectorGet(httpRequestContext, factoryServiceName, request),
541
+ requestType: {
542
+ type: "ICatalogueEntryGetRequest",
543
+ examples: [
544
+ {
545
+ id: "dataSpaceConnectorGetRequestExample",
546
+ request: {
547
+ pathParams: {
548
+ id: "https://ds-connectors.example.org/ds1"
549
+ }
550
+ }
551
+ }
552
+ ]
553
+ },
554
+ responseType: [
555
+ {
556
+ type: "IDataSpaceConnectorGetResponse",
557
+ examples: [
558
+ {
559
+ id: "dataSpaceConnectorGetResponseExample",
560
+ response: {
561
+ body: dataSpaceConnectorEntryExample
562
+ }
563
+ }
564
+ ]
565
+ }
566
+ ]
567
+ };
568
+ return [
569
+ createParticipantRoute,
570
+ createServiceOfferingRoute,
571
+ createDataResourceRoute,
572
+ createDataSpaceConnectorRoute,
573
+ listParticipantsRoute,
574
+ getParticipantRoute,
575
+ listServicesRoute,
576
+ getServiceRoute,
577
+ listDataResourcesRoute,
578
+ getDataResourceRoute,
579
+ listDataSpaceConnectorsRoute,
580
+ getDataSpaceConnectorRoute
581
+ ];
582
+ }
583
+ /**
584
+ * Register a new participant.
585
+ * @param baseRouteName The base route name.
586
+ * @param httpRequestContext The request context for the API.
587
+ * @param factoryServiceName The name of the service to use in the routes.
588
+ * @param request The request.
589
+ * @returns The response object with additional http response properties.
590
+ */
591
+ async function complianceCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request) {
592
+ core.Guards.object(ROUTES_SOURCE, "request", request);
593
+ core.Guards.stringValue(ROUTES_SOURCE, "request.body", request.body);
594
+ const service = core.ComponentFactory.get(factoryServiceName);
595
+ const participantId = await service.registerComplianceCredential(request.body);
596
+ const searchParams = new URLSearchParams();
597
+ searchParams.append("id", participantId);
598
+ return {
599
+ headers: {
600
+ location: `${baseRouteName}/${PARTICIPANTS_ROUTE}?${searchParams.toString()}`
601
+ },
602
+ statusCode: web.HttpStatusCode.created
603
+ };
604
+ }
605
+ /**
606
+ * Get a list of the participant entries.
607
+ * @param httpRequestContext The request context for the API.
608
+ * @param factoryServiceName The name of the service to use in the routes.
609
+ * @param request The request.
610
+ * @returns The response object with additional http response properties.
611
+ */
612
+ async function participantList(httpRequestContext, factoryServiceName, request) {
613
+ const service = core.ComponentFactory.get(factoryServiceName);
614
+ const itemsAndCursor = await service.queryParticipants(request?.query?.id, request?.query?.registrationNumber, request?.query?.lrnType, request?.query?.cursor, core.Coerce.number(request?.query?.pageSize));
615
+ return {
616
+ body: itemsAndCursor
617
+ };
618
+ }
619
+ /**
620
+ * Get a Participant entry.
621
+ * @param httpRequestContext The request context for the API.
622
+ * @param factoryServiceName The name of the service to use in the routes.
623
+ * @param request The request.
624
+ * @returns The response object with additional http response properties.
625
+ */
626
+ async function participantGet(httpRequestContext, factoryServiceName, request) {
627
+ const service = core.ComponentFactory.get(factoryServiceName);
628
+ const id = request?.pathParams.id;
629
+ core.Guards.stringValue(ROUTES_SOURCE, "id", id);
630
+ return {
631
+ body: (await service.getEntry(standardsGaiaX.GaiaXTypes.Participant, id))
632
+ };
633
+ }
634
+ /**
635
+ * Register a new service offering.
636
+ * @param baseRouteName The base route used.
637
+ * @param httpRequestContext The request context for the API.
638
+ * @param factoryServiceName The name of the service to use in the routes.
639
+ * @param request The request.
640
+ * @returns The response object with additional http response properties.
641
+ */
642
+ async function serviceOfferingCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request) {
643
+ core.Guards.object(ROUTES_SOURCE, "request", request);
644
+ core.Guards.stringValue(ROUTES_SOURCE, "request.body", request.body);
645
+ const service = core.ComponentFactory.get(factoryServiceName);
646
+ const serviceOfferingsCreated = await service.registerServiceOfferingCredential(request.body);
647
+ // Prepare the Ids to be returned
648
+ const searchParams = new URLSearchParams();
649
+ for (const serviceOffering of serviceOfferingsCreated) {
650
+ searchParams.append("id", serviceOffering);
651
+ }
652
+ return {
653
+ headers: {
654
+ location: `${baseRouteName}/${SERVICE_OFFERING_ROUTE}?${searchParams.toString()}`
655
+ },
656
+ statusCode: web.HttpStatusCode.created
657
+ };
658
+ }
659
+ /**
660
+ * Get a list of the service offering entries.
661
+ * @param httpRequestContext The request context for the API.
662
+ * @param factoryServiceName The name of the service to use in the routes.
663
+ * @param request The request.
664
+ * @returns The response object with additional http response properties.
665
+ */
666
+ async function serviceOfferingList(httpRequestContext, factoryServiceName, request) {
667
+ const service = core.ComponentFactory.get(factoryServiceName);
668
+ const itemsAndCursor = await service.queryServiceOfferings(request?.query.id, request?.query.providedBy, request?.query.cursor, core.Coerce.number(request?.query?.pageSize));
669
+ return {
670
+ body: itemsAndCursor
671
+ };
672
+ }
673
+ /**
674
+ * Get a Service Offering entry.
675
+ * @param httpRequestContext The request context for the API.
676
+ * @param factoryServiceName The name of the service to use in the routes.
677
+ * @param request The request.
678
+ * @returns The response object with additional http response properties.
679
+ */
680
+ async function serviceOfferingGet(httpRequestContext, factoryServiceName, request) {
681
+ const service = core.ComponentFactory.get(factoryServiceName);
682
+ const id = request?.pathParams.id;
683
+ core.Guards.stringValue(ROUTES_SOURCE, "id", id);
684
+ return {
685
+ body: (await service.getEntry(standardsGaiaX.GaiaXTypes.ServiceOffering, id))
686
+ };
687
+ }
688
+ /**
689
+ * Register a new data resource.
690
+ * @param baseRouteName The base route name.
691
+ * @param httpRequestContext The request context for the API.
692
+ * @param factoryServiceName The name of the service to use in the routes.
693
+ * @param request The request.
694
+ * @returns The response object with additional http response properties.
695
+ */
696
+ async function dataResourceCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request) {
697
+ core.Guards.object(ROUTES_SOURCE, "request", request);
698
+ core.Guards.stringValue(ROUTES_SOURCE, "request.body", request.body);
699
+ const service = core.ComponentFactory.get(factoryServiceName);
700
+ const dataResourcesCreated = await service.registerDataResourceCredential(request.body);
701
+ // Prepare the Ids to be returned
702
+ const searchParams = new URLSearchParams();
703
+ for (const dataResource of dataResourcesCreated) {
704
+ searchParams.append("id", dataResource);
705
+ }
706
+ return {
707
+ headers: {
708
+ location: `${baseRouteName}/${DATA_RESOURCE_ROUTE}?${searchParams.toString()}`
709
+ },
710
+ statusCode: web.HttpStatusCode.created
711
+ };
712
+ }
713
+ /**
714
+ * Get a list of the data resource entries.
715
+ * @param httpRequestContext The request context for the API.
716
+ * @param factoryServiceName The name of the service to use in the routes.
717
+ * @param request The request.
718
+ * @returns The response object with additional http response properties.
719
+ */
720
+ async function dataResourceList(httpRequestContext, factoryServiceName, request) {
721
+ const service = core.ComponentFactory.get(factoryServiceName);
722
+ const itemsAndCursor = await service.queryDataResources(request?.query.id, request?.query.producedBy, request?.query.cursor, core.Coerce.number(request?.query?.pageSize));
723
+ return {
724
+ body: itemsAndCursor
725
+ };
726
+ }
727
+ /**
728
+ * Get a Data Resource entry.
729
+ * @param httpRequestContext The request context for the API.
730
+ * @param factoryServiceName The name of the service to use in the routes.
731
+ * @param request The request.
732
+ * @returns The response object with additional http response properties.
733
+ */
734
+ async function dataResourceGet(httpRequestContext, factoryServiceName, request) {
735
+ const service = core.ComponentFactory.get(factoryServiceName);
736
+ const id = request?.pathParams.id;
737
+ core.Guards.stringValue(ROUTES_SOURCE, "id", id);
738
+ return {
739
+ body: (await service.getEntry(standardsGaiaX.GaiaXTypes.DataResource, id))
740
+ };
741
+ }
742
+ /**
743
+ * Register a new data space connector.
744
+ * @param baseRouteName the base route name.
745
+ * @param httpRequestContext The request context for the API.
746
+ * @param factoryServiceName The name of the service to use in the routes.
747
+ * @param request The request.
748
+ * @returns The response object with additional http response properties.
749
+ */
750
+ async function dataSpaceConnectorCredentialPresentation(baseRouteName, httpRequestContext, factoryServiceName, request) {
751
+ core.Guards.object(ROUTES_SOURCE, "request", request);
752
+ core.Guards.stringValue(ROUTES_SOURCE, "request.body", request.body);
753
+ const service = core.ComponentFactory.get(factoryServiceName);
754
+ const dataSpaceConnectorId = await service.registerDataSpaceConnectorCredential(request.body);
755
+ const searchParams = new URLSearchParams();
756
+ searchParams.append("id", dataSpaceConnectorId);
757
+ return {
758
+ headers: {
759
+ location: `${baseRouteName}/${DATA_SPACE_CONNECTOR_ROUTE}?${searchParams.toString()}`
760
+ },
761
+ statusCode: web.HttpStatusCode.created
762
+ };
763
+ }
764
+ /**
765
+ * Get a list of the data space connector entries.
766
+ * @param httpRequestContext The request context for the API.
767
+ * @param factoryServiceName The name of the service to use in the routes.
768
+ * @param request The request.
769
+ * @returns The response object with additional http response properties.
770
+ */
771
+ async function dataSpaceConnectorList(httpRequestContext, factoryServiceName, request) {
772
+ const service = core.ComponentFactory.get(factoryServiceName);
773
+ const itemsAndCursor = await service.queryDataSpaceConnectors(request?.query.id, request?.query.maintainedBy, request?.query.cursor, core.Coerce.number(request?.query?.pageSize));
774
+ return {
775
+ body: itemsAndCursor
776
+ };
777
+ }
778
+ /**
779
+ * Get a Data Space Connector entry.
780
+ * @param httpRequestContext The request context for the API.
781
+ * @param factoryServiceName The name of the service to use in the routes.
782
+ * @param request The request.
783
+ * @returns The response object with additional http response properties.
784
+ */
785
+ async function dataSpaceConnectorGet(httpRequestContext, factoryServiceName, request) {
786
+ const service = core.ComponentFactory.get(factoryServiceName);
787
+ const id = request?.pathParams.id;
788
+ core.Guards.stringValue(ROUTES_SOURCE, "id", id);
789
+ return {
790
+ body: (await service.getEntry(standardsGaiaX.GaiaXTypes.DataExchangeComponent, id))
791
+ };
792
+ }
793
+
794
+ // Copyright 2024 IOTA Stiftung.
795
+ // SPDX-License-Identifier: Apache-2.0.
796
+ /**
797
+ * Compliance Credential Verification Service.
798
+ */
799
+ class ComplianceCredentialVerificationService {
800
+ /**
801
+ * Class name
802
+ */
803
+ CLASS_NAME = "ComplianceCredentialVerificationService";
804
+ /**
805
+ * Resolver component.
806
+ * @internal
807
+ */
808
+ _resolver;
809
+ /**
810
+ * Resolver component.
811
+ * @internal
812
+ */
813
+ _subResourceCacheTtlMs;
814
+ /**
815
+ * Logging Component.
816
+ * @internal
817
+ */
818
+ _logger;
819
+ /**
820
+ * List of clearing houses tha are approvers.
821
+ * @internal
822
+ */
823
+ _clearingHouseApproverList;
824
+ /**
825
+ * Constructor.
826
+ * @param clearingHouseApproverList The list of clearing house identities approved.
827
+ * @param resolver The resolver used for DID.
828
+ * @param subResourceCacheTtlMs The time to live (in ms) of sub-resource objects in the cache. undefined means no cache. 0 means live in cache forever.
829
+ * @param logger The Logger Component.
830
+ */
831
+ constructor(clearingHouseApproverList, resolver, subResourceCacheTtlMs, logger) {
832
+ this._clearingHouseApproverList = clearingHouseApproverList;
833
+ this._resolver = resolver;
834
+ this._subResourceCacheTtlMs = subResourceCacheTtlMs;
835
+ this._logger = logger;
836
+ }
837
+ /**
838
+ * Verifies a Compliance Credential.
839
+ * @param credential The Credential to be verified
840
+ * @returns The Verification Result.
841
+ */
842
+ async verify(credential) {
843
+ if (!core.Is.arrayValue(credential.type) ||
844
+ !credential.type.includes(federatedCatalogueModels.FederatedCatalogueTypes.ComplianceCredential)) {
845
+ return {
846
+ verified: false,
847
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.InvalidCredentialType,
848
+ credentials: []
849
+ };
850
+ }
851
+ const issuer = core.Is.string(credential.issuer)
852
+ ? credential.issuer
853
+ : core.Coerce.object(credential.issuer)?.id;
854
+ if (core.Is.undefined(issuer)) {
855
+ return {
856
+ verified: false,
857
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.InvalidIssuer,
858
+ credentials: []
859
+ };
860
+ }
861
+ if (!this._clearingHouseApproverList.includes(issuer)) {
862
+ return {
863
+ verified: false,
864
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.InvalidIssuer,
865
+ credentials: []
866
+ };
867
+ }
868
+ const validFrom = credential.validFrom;
869
+ const validFromDate = core.Coerce.dateTime(validFrom);
870
+ if (core.Is.undefined(validFromDate) || validFromDate.getTime() > Date.now()) {
871
+ return {
872
+ verified: false,
873
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.NotValidYet,
874
+ credentials: []
875
+ };
876
+ }
877
+ const validUntilDate = core.Coerce.dateTime(credential.validUntil);
878
+ if (core.Is.undefined(validUntilDate)) {
879
+ return {
880
+ verified: false,
881
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.NoValidityEndPeriod,
882
+ credentials: []
883
+ };
884
+ }
885
+ if (validUntilDate.getTime() <= Date.now()) {
886
+ return {
887
+ verified: false,
888
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.Expired,
889
+ credentials: []
890
+ };
891
+ }
892
+ const subject = credential.credentialSubject;
893
+ if (!subject) {
894
+ return {
895
+ verified: false,
896
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.MissingSubject,
897
+ credentials: []
898
+ };
899
+ }
900
+ const evidences = core.Is.array(credential.evidence) ? credential.evidence : [credential.evidence];
901
+ if (evidences.length === 0) {
902
+ return {
903
+ verified: false,
904
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.MissingEvidences,
905
+ credentials: []
906
+ };
907
+ }
908
+ const finalResult = {
909
+ verified: true,
910
+ credentials: []
911
+ };
912
+ for (const evidence of evidences) {
913
+ const verResult = await this.verifyEvidence(evidence);
914
+ if (!verResult.verified) {
915
+ return {
916
+ verified: false,
917
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.EvidenceCannotBeVerified,
918
+ evidenceVerificationResult: verResult,
919
+ credentials: [],
920
+ evidenceFailedToVerify: [evidence.id]
921
+ };
922
+ }
923
+ finalResult.credentials.push(verResult.credential);
924
+ }
925
+ return finalResult;
926
+ }
927
+ /**
928
+ * Verifies the evidence supplied as part of a Compliance Credential.
929
+ * @param evidence The compliance evidence
930
+ * @returns The verification result with the original credentials that served as evidence
931
+ */
932
+ async verifyEvidence(evidence) {
933
+ // The credential associated to the evidence has to be retrieved, then verified
934
+ core.Guards.object(this.CLASS_NAME, "IComplianceEvidence", evidence);
935
+ const credentialUrl = evidence.id;
936
+ this._logger?.log({
937
+ source: this.CLASS_NAME,
938
+ level: "info",
939
+ message: "verifyingEvidenceCredential",
940
+ ts: Date.now(),
941
+ data: {
942
+ credentialUrl
943
+ }
944
+ });
945
+ const credentialResponse = await web.FetchHelper.fetch(this.CLASS_NAME, credentialUrl, "GET", undefined, { cacheTtlMs: this._subResourceCacheTtlMs });
946
+ if (!credentialResponse.ok) {
947
+ this._logger?.log({
948
+ source: this.CLASS_NAME,
949
+ level: "error",
950
+ message: "credentialCannotBeRetrieved",
951
+ ts: Date.now(),
952
+ data: {
953
+ credentialUrl,
954
+ statusCode: credentialResponse.status
955
+ }
956
+ });
957
+ return {
958
+ verified: false,
959
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.EvidenceCannotBeRetrieved
960
+ };
961
+ }
962
+ const originalCredential = await credentialResponse.json();
963
+ const theCredential = core.ObjectHelper.clone(originalCredential);
964
+ const proof = theCredential.proof;
965
+ // The proof is not taken into account to calculate the hash
966
+ delete theCredential.proof;
967
+ // Checking the hash
968
+ const canonicalized = core.JsonHelper.canonicalize(theCredential);
969
+ const hashingDetails = evidence.digestSRI;
970
+ const [hashingAlg, hash] = hashingDetails.split("-");
971
+ let hashToCheck = "";
972
+ if (hashingAlg === "sha256") {
973
+ hashToCheck = core.Converter.bytesToBase64(crypto.Sha256.sum256(core.Converter.utf8ToBytes(canonicalized)));
974
+ }
975
+ else if (hashingAlg === "sha512") {
976
+ hashToCheck = core.Converter.bytesToBase64(crypto.Sha512.sum512(core.Converter.utf8ToBytes(canonicalized)));
977
+ }
978
+ else {
979
+ throw new core.UnprocessableError(this.CLASS_NAME, "unknownHashingAlgorithm", { hashingAlg });
980
+ }
981
+ if (hashToCheck !== hash) {
982
+ return {
983
+ verified: false,
984
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.IntegrityCheckFailed
985
+ };
986
+ }
987
+ const { id } = identityModels.DocumentHelper.parseId(proof.verificationMethod);
988
+ const documentId = theCredential.issuer ?? id;
989
+ core.Guards.stringValue(this.CLASS_NAME, "documentId", documentId);
990
+ let verified = false;
991
+ try {
992
+ const document = await this._resolver.identityResolve(documentId);
993
+ const jwk = identityModels.DocumentHelper.getJwk(document, proof.verificationMethod);
994
+ verified = await standardsW3cDid.ProofHelper.verifyProof(theCredential, proof, jwk);
995
+ }
996
+ catch (error) {
997
+ this._logger?.log({
998
+ source: this.CLASS_NAME,
999
+ level: "error",
1000
+ message: "credentialVerificationError",
1001
+ ts: Date.now(),
1002
+ error: error,
1003
+ data: {
1004
+ credentialUrl
1005
+ }
1006
+ });
1007
+ return {
1008
+ verified,
1009
+ verificationFailureReason: federatedCatalogueModels.VerificationFailureReasons.GeneralVerificationError
1010
+ };
1011
+ }
1012
+ this._logger?.log({
1013
+ source: this.CLASS_NAME,
1014
+ level: "info",
1015
+ message: "credentialEvidenceVerified",
1016
+ ts: Date.now(),
1017
+ data: {
1018
+ credentialUrl
1019
+ }
1020
+ });
1021
+ return {
1022
+ verified: true,
1023
+ credential: originalCredential
1024
+ };
1025
+ }
1026
+ }
1027
+
1028
+ // Copyright 2024 IOTA Stiftung.
1029
+ // SPDX-License-Identifier: Apache-2.0.
1030
+ /**
1031
+ * Service for performing logging operations to a connector.
1032
+ */
1033
+ class FederatedCatalogueService {
1034
+ /**
1035
+ * The namespace for the service.
1036
+ */
1037
+ static NAMESPACE = "fedcat";
1038
+ /**
1039
+ * Fields to skip when persisting entries to the Catalogue
1040
+ * @internal
1041
+ */
1042
+ static _FIELDS_TO_SKIP = ["@context", "type"];
1043
+ /**
1044
+ * Runtime name for the class.
1045
+ */
1046
+ CLASS_NAME = "FederatedCatalogueService";
1047
+ /**
1048
+ * The identity resolver used to dereference DIDs.
1049
+ * @internal
1050
+ */
1051
+ _resolver;
1052
+ /**
1053
+ * Logging service.
1054
+ * @internal
1055
+ */
1056
+ _loggingService;
1057
+ /**
1058
+ * Storage service for participants.
1059
+ * @internal
1060
+ */
1061
+ _entityStorageParticipants;
1062
+ /**
1063
+ * Storage service for service offering.
1064
+ * @internal
1065
+ */
1066
+ _entityStorageServiceOfferings;
1067
+ /**
1068
+ * Storage service for data resources.
1069
+ * @internal
1070
+ */
1071
+ _entityStorageDataResources;
1072
+ /**
1073
+ * Storage service for data resources.
1074
+ * @internal
1075
+ */
1076
+ _entityStorageDataSpaceConnectors;
1077
+ /**
1078
+ * Compliance Credential Verifier service.
1079
+ * @internal
1080
+ */
1081
+ _complianceCredentialVerifier;
1082
+ /**
1083
+ * Create a new instance of FederatedCatalogue service.
1084
+ * @param options The options for the connector.
1085
+ */
1086
+ constructor(options) {
1087
+ this._loggingService = loggingModels.LoggingConnectorFactory.getIfExists(options?.loggingConnectorType ?? "logging");
1088
+ this._entityStorageParticipants = entityStorageModels.EntityStorageConnectorFactory.get(options.participantEntityStorageType ?? core.StringHelper.kebabCase("ParticipantEntry"));
1089
+ this._entityStorageServiceOfferings = entityStorageModels.EntityStorageConnectorFactory.get(options.serviceOfferingEntityStorageType ??
1090
+ core.StringHelper.kebabCase("ServiceOfferingEntry"));
1091
+ this._entityStorageDataResources = entityStorageModels.EntityStorageConnectorFactory.get(options.dataResourceEntityStorageType ?? core.StringHelper.kebabCase("DataResourceEntry"));
1092
+ this._entityStorageDataSpaceConnectors = entityStorageModels.EntityStorageConnectorFactory.get(options.dataSpaceConnectorStorageType ??
1093
+ core.StringHelper.kebabCase("DataSpaceConnectorEntry"));
1094
+ this._resolver = core.ComponentFactory.get(options.identityResolverComponentType ?? "identity-resolver");
1095
+ this._complianceCredentialVerifier = new ComplianceCredentialVerificationService(options.config.clearingHouseApproverList, this._resolver, options.config.subResourceCacheTtlMs, this._loggingService);
1096
+ standardsSchemaOrg.SchemaOrgDataTypes.registerRedirects();
1097
+ }
1098
+ /**
1099
+ * Registers a Participant's compliance Credential.
1100
+ * @param credentialJwt The credential (wrapped into a presentation) as JWT.
1101
+ * @returns The Id of the Participant (DID usually).
1102
+ */
1103
+ async registerComplianceCredential(credentialJwt) {
1104
+ core.Guards.string(this.CLASS_NAME, "credentialJwt", credentialJwt);
1105
+ // This will raise exceptions as it has been coded reusing code from Gaia-X
1106
+ const complianceCredential = await this.decodeJwt(credentialJwt);
1107
+ const result = await this._complianceCredentialVerifier.verify(complianceCredential);
1108
+ if (!result.verified) {
1109
+ this._loggingService?.log({
1110
+ level: "error",
1111
+ source: this.CLASS_NAME,
1112
+ ts: Date.now(),
1113
+ message: "complianceCredentialNotVerified",
1114
+ data: { result }
1115
+ });
1116
+ throw new core.UnprocessableError(this.CLASS_NAME, "complianceCredentialNotVerified", {
1117
+ reason: result.verificationFailureReason
1118
+ });
1119
+ }
1120
+ const targetCredential = result.credentials.find(credential => credential.credentialSubject.type === standardsGaiaX.GaiaXTypes.Participant);
1121
+ if (core.Is.undefined(targetCredential)) {
1122
+ throw new core.UnprocessableError(this.CLASS_NAME, "noEvidence");
1123
+ }
1124
+ const participantEntry = this.extractParticipantEntry(complianceCredential, targetCredential);
1125
+ const theEntry = core.ObjectHelper.omit(participantEntry, FederatedCatalogueService._FIELDS_TO_SKIP);
1126
+ await this._entityStorageParticipants.set(theEntry);
1127
+ await this._loggingService?.log({
1128
+ level: "info",
1129
+ source: this.CLASS_NAME,
1130
+ ts: Date.now(),
1131
+ message: "complianceCredentialVerified",
1132
+ data: {
1133
+ participantId: complianceCredential.credentialSubject?.id,
1134
+ trustedIssuer: complianceCredential.issuer
1135
+ }
1136
+ });
1137
+ return participantEntry.id;
1138
+ }
1139
+ /**
1140
+ * Query the federated catalogue.
1141
+ * @param id The identity of the participant.
1142
+ * @param legalRegistrationNumber The legal registration number.
1143
+ * @param lrnType The legal registration number type (EORI, VATID, GLEIF, KENYA_PIN, etc.)
1144
+ * @param cursor The cursor to request the next page of entities.
1145
+ * @param pageSize The maximum number of entities in a page.
1146
+ * @returns All the entities for the storage matching the conditions,
1147
+ * and a cursor which can be used to request more entities.
1148
+ * @throws NotImplementedError if the implementation does not support retrieval.
1149
+ */
1150
+ async queryParticipants(id, legalRegistrationNumber, lrnType, cursor, pageSize) {
1151
+ const conditions = [];
1152
+ if (core.Is.stringValue(id)) {
1153
+ const condition = {
1154
+ property: "id",
1155
+ value: id,
1156
+ comparison: entity.ComparisonOperator.Equals
1157
+ };
1158
+ conditions.push(condition);
1159
+ }
1160
+ if (core.Is.stringValue(lrnType)) {
1161
+ const condition = {
1162
+ property: "lrnType",
1163
+ value: lrnType,
1164
+ comparison: entity.ComparisonOperator.Equals
1165
+ };
1166
+ conditions.push(condition);
1167
+ }
1168
+ if (core.Is.stringValue(legalRegistrationNumber)) {
1169
+ const condition = {
1170
+ property: "registrationNumber",
1171
+ value: legalRegistrationNumber,
1172
+ comparison: entity.ComparisonOperator.Equals
1173
+ };
1174
+ conditions.push(condition);
1175
+ }
1176
+ const entries = await this._entityStorageParticipants.query({ conditions }, undefined, undefined, cursor, pageSize);
1177
+ const itemList = entries.entities.map(entry => {
1178
+ entry.type = standardsGaiaX.GaiaXTypes.Participant;
1179
+ return entry;
1180
+ });
1181
+ const result = {
1182
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
1183
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
1184
+ itemListElement: itemList,
1185
+ nextItem: entries.cursor
1186
+ };
1187
+ return dataJsonLd.JsonLdProcessor.compact(result, result["@context"]);
1188
+ }
1189
+ /**
1190
+ * Returns a Federated Catalogue entry.
1191
+ * @param entryType The type of entry.
1192
+ * @param entryId The entry's id.
1193
+ * @returns Catalogue Entry
1194
+ * @throws NotFoundError if not found.
1195
+ */
1196
+ async getEntry(entryType, entryId) {
1197
+ core.Guards.stringValue(this.CLASS_NAME, "entryId", entryId);
1198
+ let itemsAndCursor;
1199
+ switch (entryType) {
1200
+ case standardsGaiaX.GaiaXTypes.Participant:
1201
+ itemsAndCursor = await this.queryParticipants(entryId);
1202
+ break;
1203
+ case standardsGaiaX.GaiaXTypes.DataExchangeComponent:
1204
+ case federatedCatalogueModels.FederatedCatalogueTypes.DataSpaceConnector:
1205
+ itemsAndCursor = await this.queryDataSpaceConnectors(entryId);
1206
+ break;
1207
+ case standardsGaiaX.GaiaXTypes.ServiceOffering:
1208
+ itemsAndCursor = await this.queryServiceOfferings(entryId);
1209
+ break;
1210
+ case standardsGaiaX.GaiaXTypes.DataResource:
1211
+ itemsAndCursor = await this.queryDataResources(entryId);
1212
+ break;
1213
+ default:
1214
+ throw new core.GeneralError(this.CLASS_NAME, "unknownEntryType", { entryType });
1215
+ }
1216
+ if (core.Is.arrayValue(itemsAndCursor?.itemListElement)) {
1217
+ const entry = {
1218
+ ...itemsAndCursor.itemListElement[0],
1219
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY
1220
+ };
1221
+ const result = await dataJsonLd.JsonLdProcessor.compact(entry, entry["@context"]);
1222
+ return result;
1223
+ }
1224
+ throw new core.NotFoundError(this.CLASS_NAME, "entryNotFound", entryId);
1225
+ }
1226
+ /**
1227
+ * Registers a compliance Credential concerning a Data Space Connector.
1228
+ * @param credentialJwt The credential (wrapped into a presentation) as JWT.
1229
+ * @returns The identifier of the Data Space Connector registered.
1230
+ */
1231
+ async registerDataSpaceConnectorCredential(credentialJwt) {
1232
+ core.Guards.string(this.CLASS_NAME, "credentialJwt", credentialJwt);
1233
+ // This will raise exceptions as it has been coded reusing code from Gaia-X
1234
+ const complianceCredential = await this.decodeJwt(credentialJwt);
1235
+ const result = await this._complianceCredentialVerifier.verify(complianceCredential);
1236
+ if (!result.verified) {
1237
+ this._loggingService?.log({
1238
+ level: "error",
1239
+ source: this.CLASS_NAME,
1240
+ ts: Date.now(),
1241
+ message: "complianceCredentialNotVerified",
1242
+ data: { result }
1243
+ });
1244
+ throw new core.UnprocessableError(this.CLASS_NAME, "complianceCredentialNotVerified", {
1245
+ reason: result.verificationFailureReason
1246
+ });
1247
+ }
1248
+ const targetCredential = result.credentials.find(credential => {
1249
+ if (core.Is.array(credential.credentialSubject.type)) {
1250
+ return credential.credentialSubject.type.includes(federatedCatalogueModels.FederatedCatalogueTypes.DataSpaceConnector);
1251
+ }
1252
+ return credential.credentialSubject.type === federatedCatalogueModels.FederatedCatalogueTypes.DataSpaceConnector;
1253
+ });
1254
+ const dataResourceCredentials = result.credentials.filter(credential => credential.credentialSubject.type === standardsGaiaX.GaiaXTypes.DataResource);
1255
+ if (core.Is.undefined(targetCredential)) {
1256
+ throw new core.UnprocessableError(this.CLASS_NAME, "noEvidence");
1257
+ }
1258
+ await this.checkParticipantExists(targetCredential.issuer);
1259
+ const dataSpaceConnectorEntry = this.extractDataSpaceConnectorEntry(complianceCredential, result.credentials[0]);
1260
+ const theEntry = core.ObjectHelper.omit(dataSpaceConnectorEntry, FederatedCatalogueService._FIELDS_TO_SKIP);
1261
+ await this._entityStorageDataSpaceConnectors.set(theEntry);
1262
+ for (const dataResourceCredential of dataResourceCredentials) {
1263
+ await this.checkParticipantExists(dataResourceCredential.issuer);
1264
+ const dataResourceEntry = this.extractDataResourceEntry(complianceCredential, dataResourceCredential);
1265
+ const drEntry = core.ObjectHelper.omit(dataResourceEntry, FederatedCatalogueService._FIELDS_TO_SKIP);
1266
+ await this._entityStorageDataResources.set(drEntry);
1267
+ }
1268
+ await this._loggingService?.log({
1269
+ level: "info",
1270
+ source: this.CLASS_NAME,
1271
+ ts: Date.now(),
1272
+ message: "complianceCredentialVerified",
1273
+ data: {
1274
+ dataSpaceConnectorId: complianceCredential.credentialSubject?.id,
1275
+ trustedIssuer: complianceCredential.issuer
1276
+ }
1277
+ });
1278
+ return dataSpaceConnectorEntry.id;
1279
+ }
1280
+ /**
1281
+ * Registers a data resource Credential concerning a Data Space Connector.
1282
+ * @param credentialJwt The credential (wrapped into a presentation) as JWT.
1283
+ * @returns The list of Data Resources created.
1284
+ */
1285
+ async registerDataResourceCredential(credentialJwt) {
1286
+ core.Guards.string(this.CLASS_NAME, "credentialJwt", credentialJwt);
1287
+ const complianceCredential = await this.decodeJwt(credentialJwt);
1288
+ const result = await this._complianceCredentialVerifier.verify(complianceCredential);
1289
+ if (!result.verified) {
1290
+ this._loggingService?.log({
1291
+ level: "error",
1292
+ source: this.CLASS_NAME,
1293
+ ts: Date.now(),
1294
+ message: "complianceCredentialNotVerified",
1295
+ data: { result }
1296
+ });
1297
+ throw new core.UnprocessableError(this.CLASS_NAME, "complianceCredentialNotVerified", {
1298
+ reason: result.verificationFailureReason
1299
+ });
1300
+ }
1301
+ const dataResourceCredentials = result.credentials.filter(credential => credential.credentialSubject.type === standardsGaiaX.GaiaXTypes.DataResource);
1302
+ if (dataResourceCredentials.length === 0) {
1303
+ throw new core.UnprocessableError(this.CLASS_NAME, "noEvidence");
1304
+ }
1305
+ const dataResourceIds = [];
1306
+ for (const dataResourceCredential of dataResourceCredentials) {
1307
+ await this.checkParticipantExists(dataResourceCredential.issuer);
1308
+ const dataResourceEntry = this.extractDataResourceEntry(complianceCredential, dataResourceCredential);
1309
+ const theEntry = core.ObjectHelper.omit(dataResourceEntry, FederatedCatalogueService._FIELDS_TO_SKIP);
1310
+ await this._entityStorageDataResources.set(theEntry);
1311
+ dataResourceIds.push(dataResourceEntry.id);
1312
+ }
1313
+ await this._loggingService?.log({
1314
+ level: "info",
1315
+ source: this.CLASS_NAME,
1316
+ ts: Date.now(),
1317
+ message: "complianceCredentialVerified",
1318
+ data: {
1319
+ dataResourceIds,
1320
+ trustedIssuer: complianceCredential.issuer
1321
+ }
1322
+ });
1323
+ return dataResourceIds;
1324
+ }
1325
+ /**
1326
+ * Query the federated catalogue.
1327
+ * @param id The identity of the participant.
1328
+ * @param maintainer The DS Connector maintainer.
1329
+ * @param cursor The cursor to request the next page of entities.
1330
+ * @param pageSize The maximum number of entities in a page.
1331
+ * @returns All the entities for the storage matching the conditions,
1332
+ * and a cursor which can be used to request more entities.
1333
+ * @throws NotImplementedError if the implementation does not support retrieval.
1334
+ */
1335
+ async queryDataSpaceConnectors(id, maintainer, cursor, pageSize) {
1336
+ const conditions = [];
1337
+ if (core.Is.stringValue(id)) {
1338
+ const condition = {
1339
+ property: "id",
1340
+ value: id,
1341
+ comparison: entity.ComparisonOperator.Equals
1342
+ };
1343
+ conditions.push(condition);
1344
+ }
1345
+ if (core.Is.stringValue(maintainer)) {
1346
+ const condition = {
1347
+ property: "maintainer",
1348
+ value: maintainer,
1349
+ comparison: entity.ComparisonOperator.Equals
1350
+ };
1351
+ conditions.push(condition);
1352
+ }
1353
+ const entries = await this._entityStorageDataSpaceConnectors.query({ conditions }, undefined, undefined, cursor, pageSize);
1354
+ const itemList = entries.entities.map(entry => {
1355
+ entry.type = [
1356
+ standardsGaiaX.GaiaXTypes.DataExchangeComponent,
1357
+ federatedCatalogueModels.FederatedCatalogueTypes.DataSpaceConnector
1358
+ ];
1359
+ return entry;
1360
+ });
1361
+ const result = {
1362
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
1363
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
1364
+ itemListElement: itemList,
1365
+ nextItem: entries.cursor
1366
+ };
1367
+ return dataJsonLd.JsonLdProcessor.compact(result, result["@context"]);
1368
+ }
1369
+ /**
1370
+ * Registers a Service Offering Credential.
1371
+ * @param credentialJwt The credential (wrapped into a presentation) as JWT.
1372
+ * @returns Nothing.
1373
+ */
1374
+ async registerServiceOfferingCredential(credentialJwt) {
1375
+ core.Guards.string(this.CLASS_NAME, "credentialJwt", credentialJwt);
1376
+ // This will raise exceptions as it has been coded reusing code from Gaia-X
1377
+ const sdComplianceCredential = await this.decodeJwt(credentialJwt);
1378
+ const result = await this._complianceCredentialVerifier.verify(sdComplianceCredential);
1379
+ if (!result.verified) {
1380
+ this._loggingService?.log({
1381
+ level: "error",
1382
+ source: this.CLASS_NAME,
1383
+ ts: Date.now(),
1384
+ message: "complianceCredentialNotVerified",
1385
+ data: { result }
1386
+ });
1387
+ throw new core.UnprocessableError(this.CLASS_NAME, "complianceCredentialNotVerified", {
1388
+ reason: result.verificationFailureReason
1389
+ });
1390
+ }
1391
+ const serviceOfferingCredentials = result.credentials.filter(credential => credential.credentialSubject.type === standardsGaiaX.GaiaXTypes.ServiceOffering);
1392
+ const dataResourceCredentials = result.credentials.filter(credential => credential.credentialSubject.type === standardsGaiaX.GaiaXTypes.DataResource);
1393
+ if (serviceOfferingCredentials.length === 0) {
1394
+ throw new core.UnprocessableError(this.CLASS_NAME, "noEvidence");
1395
+ }
1396
+ const serviceOfferingIds = [];
1397
+ for (const serviceOfferingCredential of serviceOfferingCredentials) {
1398
+ const serviceIssuer = serviceOfferingCredential.issuer;
1399
+ await this.checkParticipantExists(serviceIssuer);
1400
+ const serviceOfferingEntry = this.extractServiceOfferingEntry(sdComplianceCredential, serviceOfferingCredential);
1401
+ const theEntry = core.ObjectHelper.omit(serviceOfferingEntry, FederatedCatalogueService._FIELDS_TO_SKIP);
1402
+ await this._entityStorageServiceOfferings.set(theEntry);
1403
+ serviceOfferingIds.push(serviceOfferingEntry.id);
1404
+ }
1405
+ for (const dataResourceCredential of dataResourceCredentials) {
1406
+ await this.checkParticipantExists(dataResourceCredential.issuer);
1407
+ const dataResourceEntry = this.extractDataResourceEntry(sdComplianceCredential, dataResourceCredential);
1408
+ await this._entityStorageDataResources.set(dataResourceEntry);
1409
+ }
1410
+ await this._loggingService?.log({
1411
+ level: "info",
1412
+ source: this.CLASS_NAME,
1413
+ ts: Date.now(),
1414
+ message: "complianceCredentialVerified",
1415
+ data: {
1416
+ serviceOfferingIds,
1417
+ trustedIssuer: sdComplianceCredential.issuer
1418
+ }
1419
+ });
1420
+ return serviceOfferingIds;
1421
+ }
1422
+ /**
1423
+ * Query the federated catalogue.
1424
+ * @param id Service Id.
1425
+ * @param providedBy The identity of the participant.
1426
+ * @param cursor The cursor to request the next page of entities.
1427
+ * @param pageSize The maximum number of entities in a page.
1428
+ * @returns All the entities for the storage matching the conditions,
1429
+ * and a cursor which can be used to request more entities.
1430
+ * @throws NotImplementedError if the implementation does not support retrieval.
1431
+ */
1432
+ async queryServiceOfferings(id, providedBy, cursor, pageSize) {
1433
+ const conditions = [];
1434
+ if (core.Is.stringValue(providedBy)) {
1435
+ const condition = {
1436
+ property: "providedBy",
1437
+ value: providedBy,
1438
+ comparison: entity.ComparisonOperator.Equals
1439
+ };
1440
+ conditions.push(condition);
1441
+ }
1442
+ if (core.Is.stringValue(id)) {
1443
+ const condition = {
1444
+ property: "id",
1445
+ value: id,
1446
+ comparison: entity.ComparisonOperator.Equals
1447
+ };
1448
+ conditions.push(condition);
1449
+ }
1450
+ const entries = await this._entityStorageServiceOfferings.query({ conditions }, undefined, undefined, cursor, pageSize);
1451
+ const itemList = entries.entities.map(entry => {
1452
+ entry.type = standardsGaiaX.GaiaXTypes.ServiceOffering;
1453
+ return entry;
1454
+ });
1455
+ const result = {
1456
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
1457
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
1458
+ itemListElement: itemList,
1459
+ nextItem: entries.cursor
1460
+ };
1461
+ return dataJsonLd.JsonLdProcessor.compact(result, result["@context"]);
1462
+ }
1463
+ /**
1464
+ * Query the federated catalogue.
1465
+ * @param id The identity of the DataResource.
1466
+ * @param producedBy The identity of the participant.
1467
+ * @param cursor The cursor to request the next page of entities.
1468
+ * @param pageSize The maximum number of entities in a page.
1469
+ * @returns All the entities for the storage matching the conditions,
1470
+ * and a cursor which can be used to request more entities.
1471
+ * @throws NotImplementedError if the implementation does not support retrieval.
1472
+ */
1473
+ async queryDataResources(id, producedBy, cursor, pageSize) {
1474
+ const conditions = [];
1475
+ if (core.Is.stringValue(producedBy)) {
1476
+ const condition = {
1477
+ property: "producedBy",
1478
+ value: producedBy,
1479
+ comparison: entity.ComparisonOperator.Equals
1480
+ };
1481
+ conditions.push(condition);
1482
+ }
1483
+ if (core.Is.stringValue(id)) {
1484
+ const condition = {
1485
+ property: "id",
1486
+ value: id,
1487
+ comparison: entity.ComparisonOperator.Equals
1488
+ };
1489
+ conditions.push(condition);
1490
+ }
1491
+ const entries = await this._entityStorageDataResources.query({ conditions }, undefined, undefined, cursor, pageSize);
1492
+ const itemList = entries.entities.map(entry => {
1493
+ entry.type = standardsGaiaX.GaiaXTypes.DataResource;
1494
+ return entry;
1495
+ });
1496
+ const result = {
1497
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY_LIST,
1498
+ type: standardsSchemaOrg.SchemaOrgTypes.ItemList,
1499
+ itemListElement: itemList,
1500
+ nextItem: entries.cursor
1501
+ };
1502
+ return dataJsonLd.JsonLdProcessor.compact(result, result["@context"]);
1503
+ }
1504
+ /**
1505
+ * Decodes the JWT.
1506
+ * @param jwt JWT.
1507
+ * @returns Decoded.
1508
+ */
1509
+ async decodeJwt(jwt) {
1510
+ const { payload } = await identityModels.VerificationHelper.verifyJwt(this._resolver, jwt);
1511
+ return payload;
1512
+ }
1513
+ /**
1514
+ * Returns the trusted Issuer id.
1515
+ * @param complianceCredential The compliance credential.
1516
+ * @returns The trusted issuer.
1517
+ */
1518
+ getTrustedIssuerId(complianceCredential) {
1519
+ const trustedIssuerId = core.Is.object(complianceCredential.issuer)
1520
+ ? complianceCredential.issuer.id
1521
+ : complianceCredential.issuer;
1522
+ return trustedIssuerId;
1523
+ }
1524
+ /**
1525
+ * Extracts participant entry from the credentials.
1526
+ * @param complianceCredential Compliance credential
1527
+ * @param participantCredential The Participant credential extracted.
1528
+ * @returns Participant Entry to be saved on the Database.
1529
+ */
1530
+ extractParticipantEntry(complianceCredential, participantCredential) {
1531
+ const participantData = participantCredential.credentialSubject;
1532
+ core.Guards.objectValue(this.CLASS_NAME, "participantData", participantData);
1533
+ const evidences = [];
1534
+ for (const evidence of complianceCredential.evidence) {
1535
+ evidences.push(evidence.id);
1536
+ }
1537
+ const result = {
1538
+ ...participantData,
1539
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
1540
+ issuer: this.getTrustedIssuerId(complianceCredential),
1541
+ validFrom: complianceCredential.validFrom,
1542
+ validUntil: complianceCredential.validUntil,
1543
+ dateCreated: new Date().toISOString(),
1544
+ evidence: evidences
1545
+ };
1546
+ return result;
1547
+ }
1548
+ /**
1549
+ * Extracts Data Space Connector description entry from the credentials.
1550
+ * @param complianceCredential Compliance Credential.
1551
+ * @param dataSpaceConnectorCredential Evidence Credential.
1552
+ * @returns Service Description Entry to be saved on the Database.
1553
+ */
1554
+ extractDataSpaceConnectorEntry(complianceCredential, dataSpaceConnectorCredential) {
1555
+ const credentialData = dataSpaceConnectorCredential.credentialSubject;
1556
+ core.Guards.objectValue(this.CLASS_NAME, "credentialData", credentialData);
1557
+ const { offeredResource, ...deStructuredData } = credentialData;
1558
+ const result = {
1559
+ ...deStructuredData,
1560
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
1561
+ offeredResource: Object.keys(offeredResource),
1562
+ issuer: this.getTrustedIssuerId(complianceCredential),
1563
+ validFrom: complianceCredential.validFrom,
1564
+ validUntil: complianceCredential.validUntil,
1565
+ dateCreated: new Date().toISOString(),
1566
+ evidence: [dataSpaceConnectorCredential.id]
1567
+ };
1568
+ return result;
1569
+ }
1570
+ /**
1571
+ * Extracts service offering entry from the credentials.
1572
+ * @param complianceCredential The Compliance Credential.
1573
+ * @param serviceOfferingCredential Service Offering credential (evidence).
1574
+ * @returns Service Offering Entry to be saved on the Database.
1575
+ */
1576
+ extractServiceOfferingEntry(complianceCredential, serviceOfferingCredential) {
1577
+ const credentialData = serviceOfferingCredential.credentialSubject;
1578
+ core.Guards.objectValue(this.CLASS_NAME, "credentialData", credentialData);
1579
+ const { providedBy, aggregationOfResources, servicePolicy, ...deStructuredData } = credentialData;
1580
+ const result = {
1581
+ ...deStructuredData,
1582
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
1583
+ providedBy: core.Is.string(providedBy) ? providedBy : providedBy.id,
1584
+ aggregationOfResources: aggregationOfResources,
1585
+ issuer: this.getTrustedIssuerId(complianceCredential),
1586
+ validFrom: complianceCredential.validFrom,
1587
+ validUntil: complianceCredential.validUntil,
1588
+ dateCreated: new Date().toISOString(),
1589
+ evidence: [serviceOfferingCredential.id],
1590
+ servicePolicy: core.ArrayHelper.fromObjectOrArray(servicePolicy)
1591
+ };
1592
+ return result;
1593
+ }
1594
+ /**
1595
+ * Extracts data resource entry from the credentials.
1596
+ * @param complianceCredential The Compliance Credential.
1597
+ * @param dataResourceCredential Data Resource credential.
1598
+ * @returns DataResource Entry to be saved on the Database.
1599
+ */
1600
+ extractDataResourceEntry(complianceCredential, dataResourceCredential) {
1601
+ const credentialData = dataResourceCredential.credentialSubject;
1602
+ core.Guards.objectValue(this.CLASS_NAME, "credentialData", credentialData);
1603
+ const { producedBy, copyrightOwnedBy, exposedThrough, resourcePolicy, ...deStructuredData } = credentialData;
1604
+ let producedByValue = producedBy;
1605
+ if (core.Is.object(producedByValue)) {
1606
+ producedByValue = producedByValue.id;
1607
+ }
1608
+ let copyrightOwnedByValue = copyrightOwnedBy;
1609
+ if (core.Is.object(copyrightOwnedByValue)) {
1610
+ copyrightOwnedByValue = copyrightOwnedByValue.id;
1611
+ }
1612
+ const result = {
1613
+ ...deStructuredData,
1614
+ "@context": federatedCatalogueModels.FederatedCatalogueContextInstances.DEFAULT_LD_CONTEXT_ENTRY,
1615
+ issuer: this.getTrustedIssuerId(complianceCredential),
1616
+ producedBy: producedByValue,
1617
+ copyrightOwnedBy: copyrightOwnedByValue,
1618
+ exposedThrough: exposedThrough,
1619
+ validFrom: complianceCredential.validFrom,
1620
+ validUntil: complianceCredential.validUntil,
1621
+ dateCreated: new Date().toISOString(),
1622
+ evidence: [dataResourceCredential.id],
1623
+ resourcePolicy: core.ArrayHelper.fromObjectOrArray(resourcePolicy)
1624
+ };
1625
+ return result;
1626
+ }
1627
+ /**
1628
+ * Checks whether the Participant exists.
1629
+ * @param participantId The Participant identifier
1630
+ */
1631
+ async checkParticipantExists(participantId) {
1632
+ const participantData = await this._entityStorageParticipants.get(participantId);
1633
+ if (!participantData) {
1634
+ this._loggingService?.log({
1635
+ level: "error",
1636
+ source: this.CLASS_NAME,
1637
+ ts: Date.now(),
1638
+ message: "providerIsNotParticipant",
1639
+ data: { providedBy: participantId }
1640
+ });
1641
+ throw new core.UnprocessableError(this.CLASS_NAME, "providerIsNotParticipant", {
1642
+ providedBy: participantId
1643
+ });
1644
+ }
1645
+ }
1646
+ }
1647
+
1648
+ const restEntryPoints = [
1649
+ {
1650
+ name: "federated-catalogue",
1651
+ defaultBaseRoute: "federated-catalogue",
1652
+ tags: tagsFederatedCatalogue,
1653
+ generateRoutes: generateRestRoutesFederatedCatalogue
1654
+ }
1655
+ ];
1656
+
1657
+ // Copyright 2024 IOTA Stiftung.
1658
+ // SPDX-License-Identifier: Apache-2.0.
1659
+ /**
1660
+ * Data Resource Entry.
1661
+ */
1662
+ exports.DataResourceEntry = class DataResourceEntry {
1663
+ /**
1664
+ * The Id.
1665
+ */
1666
+ id;
1667
+ /**
1668
+ * The trusted issuer of the compliance credential
1669
+ */
1670
+ issuer;
1671
+ /**
1672
+ * The name.
1673
+ */
1674
+ name;
1675
+ /**
1676
+ * The description.
1677
+ */
1678
+ description;
1679
+ /**
1680
+ * The Id of the producer of the data described by this Data Resource.
1681
+ */
1682
+ producedBy;
1683
+ /**
1684
+ * The copyright owner
1685
+ */
1686
+ copyrightOwnedBy;
1687
+ /**
1688
+ * The license
1689
+ */
1690
+ license;
1691
+ /**
1692
+ * The data exchange component used to expose the Data Resource.
1693
+ * Only a URL pointing to the resource is stored
1694
+ */
1695
+ exposedThrough;
1696
+ /**
1697
+ * The Data Resource policy
1698
+ */
1699
+ resourcePolicy;
1700
+ /**
1701
+ * Valid from
1702
+ */
1703
+ validFrom;
1704
+ /**
1705
+ * Valid to
1706
+ */
1707
+ validUntil;
1708
+ /**
1709
+ * Date created
1710
+ */
1711
+ dateCreated;
1712
+ /**
1713
+ * Evidences
1714
+ */
1715
+ evidence;
1716
+ };
1717
+ __decorate([
1718
+ entity.property({ type: "string", isPrimary: true }),
1719
+ __metadata("design:type", String)
1720
+ ], exports.DataResourceEntry.prototype, "id", void 0);
1721
+ __decorate([
1722
+ entity.property({ type: "string" }),
1723
+ __metadata("design:type", String)
1724
+ ], exports.DataResourceEntry.prototype, "issuer", void 0);
1725
+ __decorate([
1726
+ entity.property({ type: "string" }),
1727
+ __metadata("design:type", String)
1728
+ ], exports.DataResourceEntry.prototype, "name", void 0);
1729
+ __decorate([
1730
+ entity.property({ type: "string", optional: true }),
1731
+ __metadata("design:type", String)
1732
+ ], exports.DataResourceEntry.prototype, "description", void 0);
1733
+ __decorate([
1734
+ entity.property({ type: "string", isSecondary: true }),
1735
+ __metadata("design:type", String)
1736
+ ], exports.DataResourceEntry.prototype, "producedBy", void 0);
1737
+ __decorate([
1738
+ entity.property({ type: "string" }),
1739
+ __metadata("design:type", String)
1740
+ ], exports.DataResourceEntry.prototype, "copyrightOwnedBy", void 0);
1741
+ __decorate([
1742
+ entity.property({ type: "string" }),
1743
+ __metadata("design:type", String)
1744
+ ], exports.DataResourceEntry.prototype, "license", void 0);
1745
+ __decorate([
1746
+ entity.property({ type: "string" }),
1747
+ __metadata("design:type", String)
1748
+ ], exports.DataResourceEntry.prototype, "exposedThrough", void 0);
1749
+ __decorate([
1750
+ entity.property({ type: "array" }),
1751
+ __metadata("design:type", Array)
1752
+ ], exports.DataResourceEntry.prototype, "resourcePolicy", void 0);
1753
+ __decorate([
1754
+ entity.property({ type: "string", format: "date-time" }),
1755
+ __metadata("design:type", String)
1756
+ ], exports.DataResourceEntry.prototype, "validFrom", void 0);
1757
+ __decorate([
1758
+ entity.property({ type: "string", format: "date-time" }),
1759
+ __metadata("design:type", String)
1760
+ ], exports.DataResourceEntry.prototype, "validUntil", void 0);
1761
+ __decorate([
1762
+ entity.property({ type: "string", format: "date-time", sortDirection: entity.SortDirection.Descending }),
1763
+ __metadata("design:type", String)
1764
+ ], exports.DataResourceEntry.prototype, "dateCreated", void 0);
1765
+ __decorate([
1766
+ entity.property({ type: "array" }),
1767
+ __metadata("design:type", Array)
1768
+ ], exports.DataResourceEntry.prototype, "evidence", void 0);
1769
+ exports.DataResourceEntry = __decorate([
1770
+ entity.entity()
1771
+ ], exports.DataResourceEntry);
1772
+
1773
+ // Copyright 2024 IOTA Stiftung.
1774
+ // SPDX-License-Identifier: Apache-2.0.
1775
+ /**
1776
+ * Data Space Connector Entry.
1777
+ */
1778
+ exports.DataSpaceConnectorEntry = class DataSpaceConnectorEntry {
1779
+ /**
1780
+ * The Id.
1781
+ */
1782
+ id;
1783
+ /**
1784
+ * The trusted issuer of the compliance credential.
1785
+ */
1786
+ issuer;
1787
+ /**
1788
+ * The name.
1789
+ */
1790
+ name;
1791
+ /**
1792
+ * The description.
1793
+ */
1794
+ description;
1795
+ /**
1796
+ * The identity of the Data Space Connector
1797
+ */
1798
+ identity;
1799
+ /**
1800
+ * Who maintains the Data Space Connector
1801
+ */
1802
+ maintainer;
1803
+ /**
1804
+ * The default endpoint
1805
+ */
1806
+ defaultEndpoint;
1807
+ /**
1808
+ * The activity push endpoint
1809
+ */
1810
+ pushActivityEndpoint;
1811
+ /**
1812
+ * The activity subscribe endpoint
1813
+ */
1814
+ subscriptionActivityEndpoint;
1815
+ /**
1816
+ * The pull data endpoint
1817
+ */
1818
+ pullDataEndpoint;
1819
+ /**
1820
+ * The pull data endpoint
1821
+ */
1822
+ offeredResource;
1823
+ /**
1824
+ * Valid from
1825
+ */
1826
+ validFrom;
1827
+ /**
1828
+ * Valid to
1829
+ */
1830
+ validUntil;
1831
+ /**
1832
+ * Date created
1833
+ */
1834
+ dateCreated;
1835
+ /**
1836
+ * Evidences
1837
+ */
1838
+ evidence;
1839
+ };
1840
+ __decorate([
1841
+ entity.property({ type: "string", isPrimary: true }),
1842
+ __metadata("design:type", String)
1843
+ ], exports.DataSpaceConnectorEntry.prototype, "id", void 0);
1844
+ __decorate([
1845
+ entity.property({ type: "string" }),
1846
+ __metadata("design:type", String)
1847
+ ], exports.DataSpaceConnectorEntry.prototype, "issuer", void 0);
1848
+ __decorate([
1849
+ entity.property({ type: "string", optional: true }),
1850
+ __metadata("design:type", String)
1851
+ ], exports.DataSpaceConnectorEntry.prototype, "name", void 0);
1852
+ __decorate([
1853
+ entity.property({ type: "string", optional: true }),
1854
+ __metadata("design:type", String)
1855
+ ], exports.DataSpaceConnectorEntry.prototype, "description", void 0);
1856
+ __decorate([
1857
+ entity.property({ type: "string" }),
1858
+ __metadata("design:type", String)
1859
+ ], exports.DataSpaceConnectorEntry.prototype, "identity", void 0);
1860
+ __decorate([
1861
+ entity.property({ type: "string", isSecondary: true }),
1862
+ __metadata("design:type", String)
1863
+ ], exports.DataSpaceConnectorEntry.prototype, "maintainer", void 0);
1864
+ __decorate([
1865
+ entity.property({ type: "object" }),
1866
+ __metadata("design:type", Object)
1867
+ ], exports.DataSpaceConnectorEntry.prototype, "defaultEndpoint", void 0);
1868
+ __decorate([
1869
+ entity.property({ type: "object" }),
1870
+ __metadata("design:type", Object)
1871
+ ], exports.DataSpaceConnectorEntry.prototype, "pushActivityEndpoint", void 0);
1872
+ __decorate([
1873
+ entity.property({ type: "object", optional: true }),
1874
+ __metadata("design:type", Object)
1875
+ ], exports.DataSpaceConnectorEntry.prototype, "subscriptionActivityEndpoint", void 0);
1876
+ __decorate([
1877
+ entity.property({ type: "object" }),
1878
+ __metadata("design:type", Object)
1879
+ ], exports.DataSpaceConnectorEntry.prototype, "pullDataEndpoint", void 0);
1880
+ __decorate([
1881
+ entity.property({ type: "array" }),
1882
+ __metadata("design:type", Array)
1883
+ ], exports.DataSpaceConnectorEntry.prototype, "offeredResource", void 0);
1884
+ __decorate([
1885
+ entity.property({ type: "string", format: "date-time" }),
1886
+ __metadata("design:type", String)
1887
+ ], exports.DataSpaceConnectorEntry.prototype, "validFrom", void 0);
1888
+ __decorate([
1889
+ entity.property({ type: "string", format: "date-time" }),
1890
+ __metadata("design:type", String)
1891
+ ], exports.DataSpaceConnectorEntry.prototype, "validUntil", void 0);
1892
+ __decorate([
1893
+ entity.property({ type: "string", format: "date-time", sortDirection: entity.SortDirection.Descending }),
1894
+ __metadata("design:type", String)
1895
+ ], exports.DataSpaceConnectorEntry.prototype, "dateCreated", void 0);
1896
+ __decorate([
1897
+ entity.property({ type: "array" }),
1898
+ __metadata("design:type", Array)
1899
+ ], exports.DataSpaceConnectorEntry.prototype, "evidence", void 0);
1900
+ exports.DataSpaceConnectorEntry = __decorate([
1901
+ entity.entity()
1902
+ ], exports.DataSpaceConnectorEntry);
1903
+
1904
+ // Copyright 2024 IOTA Stiftung.
1905
+ // SPDX-License-Identifier: Apache-2.0.
1906
+ /**
1907
+ * Participant entry.
1908
+ */
1909
+ exports.ParticipantEntry = class ParticipantEntry {
1910
+ /**
1911
+ * The participant Id.
1912
+ */
1913
+ id;
1914
+ /**
1915
+ * The trusted issuer of the compliance credential
1916
+ */
1917
+ issuer;
1918
+ /**
1919
+ * The legal registration number.
1920
+ */
1921
+ registrationNumber;
1922
+ /**
1923
+ * The legal name.
1924
+ */
1925
+ legalName;
1926
+ /**
1927
+ * Address
1928
+ */
1929
+ legalAddress;
1930
+ /**
1931
+ * Valid from
1932
+ */
1933
+ validFrom;
1934
+ /**
1935
+ * Valid to
1936
+ */
1937
+ validUntil;
1938
+ /**
1939
+ * Date created
1940
+ */
1941
+ dateCreated;
1942
+ /**
1943
+ * Evidences
1944
+ */
1945
+ evidence;
1946
+ };
1947
+ __decorate([
1948
+ entity.property({ type: "string", isPrimary: true }),
1949
+ __metadata("design:type", String)
1950
+ ], exports.ParticipantEntry.prototype, "id", void 0);
1951
+ __decorate([
1952
+ entity.property({ type: "string" }),
1953
+ __metadata("design:type", String)
1954
+ ], exports.ParticipantEntry.prototype, "issuer", void 0);
1955
+ __decorate([
1956
+ entity.property({ type: "object", isSecondary: true }),
1957
+ __metadata("design:type", Object)
1958
+ ], exports.ParticipantEntry.prototype, "registrationNumber", void 0);
1959
+ __decorate([
1960
+ entity.property({ type: "string", isSecondary: true }),
1961
+ __metadata("design:type", String)
1962
+ ], exports.ParticipantEntry.prototype, "legalName", void 0);
1963
+ __decorate([
1964
+ entity.property({ type: "object" }),
1965
+ __metadata("design:type", Object)
1966
+ ], exports.ParticipantEntry.prototype, "legalAddress", void 0);
1967
+ __decorate([
1968
+ entity.property({ type: "string", format: "date-time" }),
1969
+ __metadata("design:type", String)
1970
+ ], exports.ParticipantEntry.prototype, "validFrom", void 0);
1971
+ __decorate([
1972
+ entity.property({ type: "string", format: "date-time" }),
1973
+ __metadata("design:type", String)
1974
+ ], exports.ParticipantEntry.prototype, "validUntil", void 0);
1975
+ __decorate([
1976
+ entity.property({ type: "string", format: "date-time", sortDirection: entity.SortDirection.Descending }),
1977
+ __metadata("design:type", String)
1978
+ ], exports.ParticipantEntry.prototype, "dateCreated", void 0);
1979
+ __decorate([
1980
+ entity.property({ type: "array" }),
1981
+ __metadata("design:type", Array)
1982
+ ], exports.ParticipantEntry.prototype, "evidence", void 0);
1983
+ exports.ParticipantEntry = __decorate([
1984
+ entity.entity()
1985
+ ], exports.ParticipantEntry);
1986
+
1987
+ // Copyright 2024 IOTA Stiftung.
1988
+ // SPDX-License-Identifier: Apache-2.0.
1989
+ /**
1990
+ * Service Offering Entry.
1991
+ */
1992
+ exports.ServiceOfferingEntry = class ServiceOfferingEntry {
1993
+ /**
1994
+ * The service Id.
1995
+ */
1996
+ id;
1997
+ /**
1998
+ * The trusted issuer of the compliance credential associated with
1999
+ */
2000
+ issuer;
2001
+ /**
2002
+ * The service name.
2003
+ */
2004
+ name;
2005
+ /**
2006
+ * The service description.
2007
+ */
2008
+ description;
2009
+ /**
2010
+ * The provider Id
2011
+ */
2012
+ providedBy;
2013
+ /**
2014
+ * The REST endpoint
2015
+ */
2016
+ endpoint;
2017
+ /**
2018
+ * The policy
2019
+ */
2020
+ servicePolicy;
2021
+ /**
2022
+ * Resources aggregated
2023
+ */
2024
+ aggregationOfResources;
2025
+ /**
2026
+ * Valid from
2027
+ */
2028
+ validFrom;
2029
+ /**
2030
+ * Valid to
2031
+ */
2032
+ validUntil;
2033
+ /**
2034
+ * Date created
2035
+ */
2036
+ dateCreated;
2037
+ /**
2038
+ * Evidences
2039
+ */
2040
+ evidence;
2041
+ };
2042
+ __decorate([
2043
+ entity.property({ type: "string", isPrimary: true }),
2044
+ __metadata("design:type", String)
2045
+ ], exports.ServiceOfferingEntry.prototype, "id", void 0);
2046
+ __decorate([
2047
+ entity.property({ type: "string" }),
2048
+ __metadata("design:type", String)
2049
+ ], exports.ServiceOfferingEntry.prototype, "issuer", void 0);
2050
+ __decorate([
2051
+ entity.property({ type: "string" }),
2052
+ __metadata("design:type", String)
2053
+ ], exports.ServiceOfferingEntry.prototype, "name", void 0);
2054
+ __decorate([
2055
+ entity.property({ type: "string", optional: true }),
2056
+ __metadata("design:type", String)
2057
+ ], exports.ServiceOfferingEntry.prototype, "description", void 0);
2058
+ __decorate([
2059
+ entity.property({ type: "string", isSecondary: true }),
2060
+ __metadata("design:type", String)
2061
+ ], exports.ServiceOfferingEntry.prototype, "providedBy", void 0);
2062
+ __decorate([
2063
+ entity.property({ type: "object" }),
2064
+ __metadata("design:type", Object)
2065
+ ], exports.ServiceOfferingEntry.prototype, "endpoint", void 0);
2066
+ __decorate([
2067
+ entity.property({ type: "array" }),
2068
+ __metadata("design:type", Array)
2069
+ ], exports.ServiceOfferingEntry.prototype, "servicePolicy", void 0);
2070
+ __decorate([
2071
+ entity.property({ type: "array", optional: true }),
2072
+ __metadata("design:type", Array)
2073
+ ], exports.ServiceOfferingEntry.prototype, "aggregationOfResources", void 0);
2074
+ __decorate([
2075
+ entity.property({ type: "string", format: "date-time" }),
2076
+ __metadata("design:type", String)
2077
+ ], exports.ServiceOfferingEntry.prototype, "validFrom", void 0);
2078
+ __decorate([
2079
+ entity.property({ type: "string", format: "date-time" }),
2080
+ __metadata("design:type", String)
2081
+ ], exports.ServiceOfferingEntry.prototype, "validUntil", void 0);
2082
+ __decorate([
2083
+ entity.property({ type: "string", format: "date-time", sortDirection: entity.SortDirection.Descending }),
2084
+ __metadata("design:type", String)
2085
+ ], exports.ServiceOfferingEntry.prototype, "dateCreated", void 0);
2086
+ __decorate([
2087
+ entity.property({ type: "array" }),
2088
+ __metadata("design:type", Array)
2089
+ ], exports.ServiceOfferingEntry.prototype, "evidence", void 0);
2090
+ exports.ServiceOfferingEntry = __decorate([
2091
+ entity.entity()
2092
+ ], exports.ServiceOfferingEntry);
2093
+
2094
+ // Copyright 2024 IOTA Stiftung.
2095
+ // SPDX-License-Identifier: Apache-2.0.
2096
+ /**
2097
+ * Inits schemas.
2098
+ */
2099
+ function initSchema() {
2100
+ entity.EntitySchemaFactory.register("ParticipantEntry", () => entity.EntitySchemaHelper.getSchema(exports.ParticipantEntry));
2101
+ entity.EntitySchemaFactory.register("DataResourceEntry", () => entity.EntitySchemaHelper.getSchema(exports.DataResourceEntry));
2102
+ entity.EntitySchemaFactory.register("ServiceOfferingEntry", () => entity.EntitySchemaHelper.getSchema(exports.ServiceOfferingEntry));
2103
+ entity.EntitySchemaFactory.register("DataSpaceConnectorEntry", () => entity.EntitySchemaHelper.getSchema(exports.DataSpaceConnectorEntry));
2104
+ }
2105
+
2106
+ exports.FederatedCatalogueService = FederatedCatalogueService;
2107
+ exports.complianceCredentialPresentation = complianceCredentialPresentation;
2108
+ exports.dataResourceCredentialPresentation = dataResourceCredentialPresentation;
2109
+ exports.dataResourceGet = dataResourceGet;
2110
+ exports.dataResourceList = dataResourceList;
2111
+ exports.dataSpaceConnectorCredentialPresentation = dataSpaceConnectorCredentialPresentation;
2112
+ exports.dataSpaceConnectorGet = dataSpaceConnectorGet;
2113
+ exports.dataSpaceConnectorList = dataSpaceConnectorList;
2114
+ exports.generateRestRoutesFederatedCatalogue = generateRestRoutesFederatedCatalogue;
2115
+ exports.initSchema = initSchema;
2116
+ exports.participantGet = participantGet;
2117
+ exports.participantList = participantList;
2118
+ exports.restEntryPoints = restEntryPoints;
2119
+ exports.serviceOfferingCredentialPresentation = serviceOfferingCredentialPresentation;
2120
+ exports.serviceOfferingGet = serviceOfferingGet;
2121
+ exports.serviceOfferingList = serviceOfferingList;
2122
+ exports.tagsFederatedCatalogue = tagsFederatedCatalogue;