@twin.org/immutable-proof-service 0.0.1-next.3 → 0.0.1-next.31

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.
@@ -1,17 +1,83 @@
1
1
  'use strict';
2
2
 
3
+ var entity = require('@twin.org/entity');
3
4
  var core = require('@twin.org/core');
4
5
  var immutableProofModels = require('@twin.org/immutable-proof-models');
5
6
  var standardsW3cDid = require('@twin.org/standards-w3c-did');
6
7
  var web = require('@twin.org/web');
8
+ var backgroundTaskModels = require('@twin.org/background-task-models');
7
9
  var crypto = require('@twin.org/crypto');
8
10
  var dataJsonLd = require('@twin.org/data-json-ld');
9
- var dataSchemaOrg = require('@twin.org/data-schema-org');
10
- var entity = require('@twin.org/entity');
11
11
  var entityStorageModels = require('@twin.org/entity-storage-models');
12
12
  var identityModels = require('@twin.org/identity-models');
13
- var immutableStorageModels = require('@twin.org/immutable-storage-models');
14
- var vaultModels = require('@twin.org/vault-models');
13
+ var verifiableStorageModels = require('@twin.org/verifiable-storage-models');
14
+
15
+ // Copyright 2024 IOTA Stiftung.
16
+ // SPDX-License-Identifier: Apache-2.0.
17
+ /**
18
+ * Class describing the immutable proof.
19
+ */
20
+ exports.ImmutableProof = class ImmutableProof {
21
+ /**
22
+ * The id of the proof.
23
+ */
24
+ id;
25
+ /**
26
+ * The identity of the node which controls the proof.
27
+ */
28
+ nodeIdentity;
29
+ /**
30
+ * The identity of the user which created the proof.
31
+ */
32
+ userIdentity;
33
+ /**
34
+ * The date/time of when the proof was created.
35
+ */
36
+ dateCreated;
37
+ /**
38
+ * The associated id for the item.
39
+ */
40
+ proofObjectId;
41
+ /**
42
+ * The associated hash for the item.
43
+ */
44
+ proofObjectHash;
45
+ /**
46
+ * The verifiable storage id.
47
+ */
48
+ verifiableStorageId;
49
+ };
50
+ __decorate([
51
+ entity.property({ type: "string", isPrimary: true }),
52
+ __metadata("design:type", String)
53
+ ], exports.ImmutableProof.prototype, "id", void 0);
54
+ __decorate([
55
+ entity.property({ type: "string" }),
56
+ __metadata("design:type", String)
57
+ ], exports.ImmutableProof.prototype, "nodeIdentity", void 0);
58
+ __decorate([
59
+ entity.property({ type: "string" }),
60
+ __metadata("design:type", String)
61
+ ], exports.ImmutableProof.prototype, "userIdentity", void 0);
62
+ __decorate([
63
+ entity.property({ type: "string", format: "date-time", sortDirection: entity.SortDirection.Descending }),
64
+ __metadata("design:type", String)
65
+ ], exports.ImmutableProof.prototype, "dateCreated", void 0);
66
+ __decorate([
67
+ entity.property({ type: "string", optional: true }),
68
+ __metadata("design:type", String)
69
+ ], exports.ImmutableProof.prototype, "proofObjectId", void 0);
70
+ __decorate([
71
+ entity.property({ type: "string" }),
72
+ __metadata("design:type", String)
73
+ ], exports.ImmutableProof.prototype, "proofObjectHash", void 0);
74
+ __decorate([
75
+ entity.property({ type: "string", optional: true }),
76
+ __metadata("design:type", String)
77
+ ], exports.ImmutableProof.prototype, "verifiableStorageId", void 0);
78
+ exports.ImmutableProof = __decorate([
79
+ entity.entity()
80
+ ], exports.ImmutableProof);
15
81
 
16
82
  /**
17
83
  * The source used when communicating about these routes.
@@ -47,8 +113,8 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
47
113
  id: "immutableProofCreateRequestExample",
48
114
  request: {
49
115
  body: {
50
- proofObject: {
51
- "@context": "http://schema.org",
116
+ document: {
117
+ "@context": "https://schema.org",
52
118
  type: "Person",
53
119
  name: "John Smith"
54
120
  }
@@ -108,15 +174,19 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
108
174
  id: "immutableProofGetResponseExample",
109
175
  response: {
110
176
  body: {
111
- "@context": immutableProofModels.ImmutableProofTypes.ContextRoot,
177
+ "@context": [
178
+ immutableProofModels.ImmutableProofContexts.ContextRoot,
179
+ immutableProofModels.ImmutableProofContexts.ContextRootCommon
180
+ ],
112
181
  type: immutableProofModels.ImmutableProofTypes.ImmutableProof,
113
182
  id: "ais:1234567890",
183
+ nodeIdentity: "node-1",
114
184
  userIdentity: "user-1",
115
185
  proofObjectId: "test:1234567890",
116
186
  proofObjectHash: "EAOKyDN0mYQbBh91eMdVeroxQx1H4GfnRbmt6n/2L/Y=",
117
187
  proof: {
118
- "@context": standardsW3cDid.DidContexts.ContextVCDataIntegrity,
119
- type: standardsW3cDid.DidTypes.DataIntegrityProof,
188
+ "@context": standardsW3cDid.DidContexts.ContextDataIntegrity,
189
+ type: standardsW3cDid.ProofTypes.DataIntegrityProof,
120
190
  cryptosuite: standardsW3cDid.DidCryptoSuites.EdDSAJcs2022,
121
191
  created: "2024-08-22T11:56:56.272Z",
122
192
  proofPurpose: "assertionMethod",
@@ -138,15 +208,19 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
138
208
  [web.HeaderTypes.ContentType]: web.MimeTypes.JsonLd
139
209
  },
140
210
  body: {
141
- "@context": immutableProofModels.ImmutableProofTypes.ContextRoot,
211
+ "@context": [
212
+ immutableProofModels.ImmutableProofContexts.ContextRoot,
213
+ immutableProofModels.ImmutableProofContexts.ContextRootCommon
214
+ ],
142
215
  type: immutableProofModels.ImmutableProofTypes.ImmutableProof,
143
216
  id: "ais:1234567890",
217
+ nodeIdentity: "node-1",
144
218
  userIdentity: "user-1",
145
219
  proofObjectId: "test:1234567890",
146
220
  proofObjectHash: "EAOKyDN0mYQbBh91eMdVeroxQx1H4GfnRbmt6n/2L/Y=",
147
221
  proof: {
148
- "@context": standardsW3cDid.DidContexts.ContextVCDataIntegrity,
149
- type: standardsW3cDid.DidTypes.DataIntegrityProof,
222
+ "@context": standardsW3cDid.DidContexts.ContextDataIntegrity,
223
+ type: standardsW3cDid.ProofTypes.DataIntegrityProof,
150
224
  cryptosuite: standardsW3cDid.DidCryptoSuites.EdDSAJcs2022,
151
225
  created: "2024-08-22T11:56:56.272Z",
152
226
  proofPurpose: "assertionMethod",
@@ -166,8 +240,8 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
166
240
  operationId: "immutableProofVerify",
167
241
  summary: "Verify a proof",
168
242
  tag: tagsImmutableProof[0].name,
169
- method: "POST",
170
- path: `${baseRouteName}/:id`,
243
+ method: "GET",
244
+ path: `${baseRouteName}/:id/verify`,
171
245
  handler: async (httpRequestContext, request) => immutableProofVerify(httpRequestContext, componentName, request),
172
246
  requestType: {
173
247
  type: "IImmutableProofVerifyRequest",
@@ -177,13 +251,6 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
177
251
  request: {
178
252
  pathParams: {
179
253
  id: "ais:1234567890"
180
- },
181
- body: {
182
- proofObject: {
183
- "@context": "http://schema.org",
184
- type: "Person",
185
- name: "John Smith"
186
- }
187
254
  }
188
255
  }
189
256
  }
@@ -197,7 +264,7 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
197
264
  id: "immutableProofVerifyResponseExample",
198
265
  response: {
199
266
  body: {
200
- "@context": immutableProofModels.ImmutableProofTypes.ContextRoot,
267
+ "@context": immutableProofModels.ImmutableProofContexts.ContextRoot,
201
268
  type: immutableProofModels.ImmutableProofTypes.ImmutableProofVerification,
202
269
  verified: true
203
270
  }
@@ -212,7 +279,7 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
212
279
  id: "immutableProofVerifyResponseFailExample",
213
280
  response: {
214
281
  body: {
215
- "@context": immutableProofModels.ImmutableProofTypes.ContextRoot,
282
+ "@context": immutableProofModels.ImmutableProofContexts.ContextRoot,
216
283
  type: immutableProofModels.ImmutableProofTypes.ImmutableProofVerification,
217
284
  verified: false,
218
285
  failure: immutableProofModels.ImmutableProofFailure.ProofTypeMismatch
@@ -237,9 +304,9 @@ function generateRestRoutesImmutableProof(baseRouteName, componentName) {
237
304
  */
238
305
  async function immutableProofCreate(httpRequestContext, componentName, request) {
239
306
  core.Guards.object(ROUTES_SOURCE, "request", request);
240
- core.Guards.object(ROUTES_SOURCE, "request.body.proofObject", request.body.proofObject);
307
+ core.Guards.object(ROUTES_SOURCE, "request.body.document", request.body.document);
241
308
  const component = core.ComponentFactory.get(componentName);
242
- const result = await component.create(request.body.proofObject);
309
+ const result = await component.create(request.body.document, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
243
310
  return {
244
311
  statusCode: web.HttpStatusCode.created,
245
312
  headers: {
@@ -279,10 +346,9 @@ async function immutableProofVerify(httpRequestContext, componentName, request)
279
346
  core.Guards.object(ROUTES_SOURCE, "request", request);
280
347
  core.Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
281
348
  core.Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
282
- core.Guards.object(ROUTES_SOURCE, "request.body.proofObject", request.body.proofObject);
283
349
  const mimeType = request.headers?.[web.HeaderTypes.Accept] === web.MimeTypes.JsonLd ? "jsonld" : "json";
284
350
  const component = core.ComponentFactory.get(componentName);
285
- const result = await component.verify(request.pathParams.id, request.body.proofObject);
351
+ const result = await component.verify(request.pathParams.id);
286
352
  return {
287
353
  headers: {
288
354
  [web.HeaderTypes.ContentType]: mimeType === "json" ? web.MimeTypes.Json : web.MimeTypes.JsonLd
@@ -310,11 +376,6 @@ class ImmutableProofService {
310
376
  * @internal
311
377
  */
312
378
  _config;
313
- /**
314
- * The vault connector.
315
- * @internal
316
- */
317
- _vaultConnector;
318
379
  /**
319
380
  * The identity connector.
320
381
  * @internal
@@ -326,74 +387,89 @@ class ImmutableProofService {
326
387
  */
327
388
  _proofStorage;
328
389
  /**
329
- * The immutable storage for the credentials.
390
+ * The verifiable storage for the credentials.
391
+ * @internal
392
+ */
393
+ _verifiableStorage;
394
+ /**
395
+ * The background task connector.
330
396
  * @internal
331
397
  */
332
- _immutableStorage;
398
+ _backgroundTaskConnector;
333
399
  /**
334
- * The assertion method id to use for the proofs.
400
+ * The event bus component.
335
401
  * @internal
336
402
  */
337
- _assertionMethodId;
403
+ _eventBusComponent;
338
404
  /**
339
- * The proof config key id to use for the proofs.
405
+ * The verification method id to use for the proofs.
340
406
  * @internal
341
407
  */
342
- _proofConfigKeyId;
408
+ _verificationMethodId;
343
409
  /**
344
- * Are we currently processing proofs.
410
+ * The identity connector type.
345
411
  * @internal
346
412
  */
347
- _processing;
413
+ _identityConnectorType;
348
414
  /**
349
415
  * Create a new instance of ImmutableProofService.
350
416
  * @param options The dependencies for the immutable proof connector.
351
- * @param options.config The configuration for the connector.
352
- * @param options.vaultConnectorType The vault connector type, defaults to "vault".
353
- * @param options.immutableProofEntityStorageType The entity storage for proofs, defaults to "immutable-proof".
354
- * @param options.immutableStorageType The immutable storage, defaults to "immutable-storage".
355
- * @param options.identityConnectorType The identity connector type, defaults to "identity".
356
417
  */
357
418
  constructor(options) {
358
- this._vaultConnector = vaultModels.VaultConnectorFactory.get(options?.vaultConnectorType ?? "vault");
359
419
  this._proofStorage = entityStorageModels.EntityStorageConnectorFactory.get(options?.immutableProofEntityStorageType ?? core.StringHelper.kebabCase("ImmutableProof"));
360
- this._immutableStorage = immutableStorageModels.ImmutableStorageConnectorFactory.get(options?.immutableStorageType ?? "immutable-storage");
361
- this._identityConnector = identityModels.IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
420
+ this._verifiableStorage = verifiableStorageModels.VerifiableStorageConnectorFactory.get(options?.verifiableStorageType ?? "verifiable-storage");
421
+ this._identityConnectorType = options?.identityConnectorType ?? "identity";
422
+ this._identityConnector = identityModels.IdentityConnectorFactory.get(this._identityConnectorType);
423
+ this._backgroundTaskConnector = backgroundTaskModels.BackgroundTaskConnectorFactory.get(options?.backgroundTaskConnectorType ?? "background-task");
424
+ if (core.Is.stringValue(options?.eventBusComponentType)) {
425
+ this._eventBusComponent = core.ComponentFactory.get(options.eventBusComponentType);
426
+ }
362
427
  this._config = options?.config ?? {};
363
- this._assertionMethodId = this._config.assertionMethodId ?? "immutable-proof";
364
- this._proofConfigKeyId = this._config.proofConfigKeyId ?? "immutable-proof";
365
- dataSchemaOrg.SchemaOrgDataTypes.registerRedirects();
366
- this._processing = false;
428
+ this._verificationMethodId = this._config.verificationMethodId ?? "immutable-proof-assertion";
429
+ this._backgroundTaskConnector.registerHandler("immutable-proof", "@twin.org/immutable-proof-task", "processProofTask", async (task) => {
430
+ await this.finaliseTask(task);
431
+ });
367
432
  }
368
433
  /**
369
- * Create a new authentication proof.
370
- * @param proofObject The object for the proof as JSON-LD.
434
+ * Create a new proof.
435
+ * @param document The document to create the proof for.
371
436
  * @param userIdentity The identity to create the immutable proof operation with.
372
437
  * @param nodeIdentity The node identity to use for vault operations.
373
- * @returns The id of the new authentication proof.
438
+ * @returns The id of the new proof.
374
439
  */
375
- async create(proofObject, userIdentity, nodeIdentity) {
376
- core.Guards.object(this.CLASS_NAME, "proofObject", proofObject);
440
+ async create(document, userIdentity, nodeIdentity) {
441
+ core.Guards.object(this.CLASS_NAME, "document", document);
377
442
  core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
378
443
  core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
379
444
  try {
380
445
  const validationFailures = [];
381
- await dataJsonLd.JsonLdHelper.validate(proofObject, validationFailures);
382
- core.Validation.asValidationError(this.CLASS_NAME, "proofObject", validationFailures);
446
+ await dataJsonLd.JsonLdHelper.validate(document, validationFailures);
447
+ core.Validation.asValidationError(this.CLASS_NAME, "document", validationFailures);
383
448
  const id = core.Converter.bytesToHex(core.RandomHelper.generate(32), false);
384
449
  const dateCreated = new Date(Date.now()).toISOString();
385
- const proofObjectId = core.ObjectHelper.extractProperty(proofObject, ["@id", "id"], false);
386
- const hash = this.calculateHash(id, dateCreated, nodeIdentity, userIdentity, proofObject);
450
+ const proofObjectId = core.ObjectHelper.extractProperty(document, ["@id", "id"], false);
451
+ // We don't want to store the whole document in the immutable proof, as this could be large
452
+ // and also reveal information that should not be stored in the proof so we hash the document
453
+ // and store the hash
454
+ const proofObjectHash = this.calculateDocumentHash(document);
387
455
  const proofEntity = {
388
456
  id,
389
457
  nodeIdentity,
390
458
  userIdentity,
391
459
  dateCreated,
392
460
  proofObjectId,
393
- proofObjectHash: core.Converter.bytesToBase64(hash)
461
+ proofObjectHash
394
462
  };
395
463
  await this._proofStorage.set(proofEntity);
396
- this.startProcessingProofs();
464
+ const immutableProof = this.proofEntityToJsonLd(proofEntity);
465
+ const proofTaskPayload = {
466
+ proofId: id,
467
+ nodeIdentity,
468
+ identityConnectorType: this._identityConnectorType,
469
+ verificationMethodId: this._verificationMethodId,
470
+ document: immutableProof
471
+ };
472
+ await this._backgroundTaskConnector.create("immutable-proof", proofTaskPayload);
397
473
  return new core.Urn(ImmutableProofService.NAMESPACE, id).toString();
398
474
  }
399
475
  catch (error) {
@@ -401,7 +477,7 @@ class ImmutableProofService {
401
477
  }
402
478
  }
403
479
  /**
404
- * Get an authentication proof.
480
+ * Get a proof.
405
481
  * @param id The id of the proof to get.
406
482
  * @returns The proof.
407
483
  * @throws NotFoundError if the proof is not found.
@@ -416,22 +492,20 @@ class ImmutableProofService {
416
492
  });
417
493
  }
418
494
  try {
419
- const { immutableProof } = await this.internalGet(id);
420
- const compacted = await dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
421
- return compacted;
495
+ const { immutableProof } = await this.internalGet(id, false);
496
+ return dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
422
497
  }
423
498
  catch (error) {
424
499
  throw new core.GeneralError(this.CLASS_NAME, "getFailed", undefined, error);
425
500
  }
426
501
  }
427
502
  /**
428
- * Verify an authentication proof.
503
+ * Verify a proof.
429
504
  * @param id The id of the proof to verify.
430
- * @param proofObject The object to verify as JSON-LD.
431
505
  * @returns The result of the verification and any failures.
432
506
  * @throws NotFoundError if the proof is not found.
433
507
  */
434
- async verify(id, proofObject) {
508
+ async verify(id) {
435
509
  core.Guards.stringValue(this.CLASS_NAME, "id", id);
436
510
  const urnParsed = core.Urn.fromValidString(id);
437
511
  if (urnParsed.namespaceIdentifier() !== ImmutableProofService.NAMESPACE) {
@@ -441,9 +515,9 @@ class ImmutableProofService {
441
515
  });
442
516
  }
443
517
  try {
444
- const { verified, failure } = await this.internalGet(id, proofObject);
518
+ const { verified, failure } = await this.internalGet(id, true);
445
519
  return {
446
- "@context": immutableProofModels.ImmutableProofTypes.ContextRoot,
520
+ "@context": immutableProofModels.ImmutableProofContexts.ContextRoot,
447
521
  type: immutableProofModels.ImmutableProofTypes.ImmutableProofVerification,
448
522
  verified,
449
523
  failure
@@ -454,13 +528,13 @@ class ImmutableProofService {
454
528
  }
455
529
  }
456
530
  /**
457
- * Remove the immutable storage for the proof.
531
+ * Remove the verifiable storage for the proof.
458
532
  * @param id The id of the proof to remove the storage from.
459
533
  * @param nodeIdentity The node identity to use for vault operations.
460
534
  * @returns Nothing.
461
535
  * @throws NotFoundError if the proof is not found.
462
536
  */
463
- async removeImmutable(id, nodeIdentity) {
537
+ async removeVerifiable(id, nodeIdentity) {
464
538
  core.Guards.stringValue(this.CLASS_NAME, "id", id);
465
539
  core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
466
540
  const urnParsed = core.Urn.fromValidString(id);
@@ -476,14 +550,14 @@ class ImmutableProofService {
476
550
  if (core.Is.empty(streamEntity)) {
477
551
  throw new core.NotFoundError(this.CLASS_NAME, "proofNotFound", id);
478
552
  }
479
- if (core.Is.stringValue(streamEntity.immutableStorageId)) {
480
- await this._immutableStorage.remove(nodeIdentity, streamEntity.immutableStorageId);
481
- delete streamEntity.immutableStorageId;
553
+ if (core.Is.stringValue(streamEntity.verifiableStorageId)) {
554
+ await this._verifiableStorage.remove(nodeIdentity, streamEntity.verifiableStorageId);
555
+ delete streamEntity.verifiableStorageId;
482
556
  await this._proofStorage.set(streamEntity);
483
557
  }
484
558
  }
485
559
  catch (error) {
486
- throw new core.GeneralError(this.CLASS_NAME, "removeImmutableFailed", undefined, error);
560
+ throw new core.GeneralError(this.CLASS_NAME, "removeVerifiableFailed", undefined, error);
487
561
  }
488
562
  }
489
563
  /**
@@ -492,14 +566,8 @@ class ImmutableProofService {
492
566
  * @returns The hash.
493
567
  * @internal
494
568
  */
495
- calculateHash(id, dateCreated, nodeIdentity, userIdentity, proofObject) {
496
- const b2b = new crypto.Blake2b(crypto.Blake2b.SIZE_256);
497
- b2b.update(core.Converter.utf8ToBytes(id));
498
- b2b.update(core.Converter.utf8ToBytes(dateCreated));
499
- b2b.update(core.Converter.utf8ToBytes(nodeIdentity));
500
- b2b.update(core.Converter.utf8ToBytes(userIdentity));
501
- b2b.update(core.ObjectHelper.toBytes(proofObject));
502
- return b2b.digest();
569
+ calculateDocumentHash(nodeObject) {
570
+ return `sha256:${core.Converter.bytesToBase64(crypto.Sha256.sum256(core.ObjectHelper.toBytes(core.JsonHelper.canonicalize(nodeObject))))}`;
503
571
  }
504
572
  /**
505
573
  * Map the stream entity to a model.
@@ -507,99 +575,84 @@ class ImmutableProofService {
507
575
  * @returns The model.
508
576
  * @internal
509
577
  */
510
- proofEntityToModel(proofEntity) {
511
- const model = {
512
- "@context": [
513
- immutableProofModels.ImmutableProofTypes.ContextRoot,
514
- dataSchemaOrg.SchemaOrgTypes.ContextRoot,
515
- standardsW3cDid.DidContexts.ContextVCDataIntegrity
516
- ],
578
+ proofEntityToJsonLd(proofEntity) {
579
+ const jsonLd = {
580
+ "@context": [immutableProofModels.ImmutableProofContexts.ContextRoot, immutableProofModels.ImmutableProofContexts.ContextRootCommon],
517
581
  type: immutableProofModels.ImmutableProofTypes.ImmutableProof,
518
582
  id: proofEntity.id,
583
+ nodeIdentity: proofEntity.nodeIdentity,
519
584
  userIdentity: proofEntity.userIdentity,
520
585
  proofObjectId: proofEntity.proofObjectId,
521
- proofObjectHash: proofEntity.proofObjectHash
586
+ proofObjectHash: proofEntity.proofObjectHash,
587
+ verifiableStorageId: proofEntity.verifiableStorageId
522
588
  };
523
- return model;
589
+ return jsonLd;
524
590
  }
525
591
  /**
526
- * Start processing proofs.
527
- * @returns Nothing.
528
- * @internal
529
- */
530
- startProcessingProofs() {
531
- if (!this._processing) {
532
- setTimeout(async () => {
533
- await this.processProofs();
534
- }, 0);
535
- }
536
- }
537
- /**
538
- * Process the proofs.
592
+ * Process a proof.
593
+ * @param proofEntity The proof entity to process.
539
594
  * @internal
540
595
  */
541
- async processProofs() {
542
- // Get the oldest pending proof, plus one more, we can then determine whether to
543
- // trigger another process after this one
544
- const pendingProofs = await this._proofStorage.query({
545
- property: "immutableStorageId",
546
- comparison: entity.ComparisonOperator.Equals,
547
- value: undefined
548
- }, [
549
- {
550
- property: "dateCreated",
551
- sortDirection: entity.SortDirection.Ascending
596
+ async finaliseTask(task) {
597
+ if (task.status === backgroundTaskModels.TaskStatus.Success && core.Is.object(task.payload) && core.Is.object(task.result)) {
598
+ const proofEntity = await this._proofStorage.get(task.payload.proofId);
599
+ if (core.Is.object(proofEntity)) {
600
+ const immutableProof = this.proofEntityToJsonLd(proofEntity);
601
+ // As we are adding the proof to the data we update its context
602
+ immutableProof["@context"] = dataJsonLd.JsonLdProcessor.combineContexts([immutableProofModels.ImmutableProofContexts.ContextRoot, immutableProofModels.ImmutableProofContexts.ContextRootCommon], task.result.proof["@context"]);
603
+ immutableProof.proof = task.result.proof;
604
+ core.ObjectHelper.propertyDelete(immutableProof.proof, "@context");
605
+ if (core.Is.stringValue(immutableProof.proof.created)) {
606
+ proofEntity.dateCreated = immutableProof.proof.created;
607
+ }
608
+ const compacted = await dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
609
+ const verifiableCreateResult = await this._verifiableStorage.create(proofEntity.nodeIdentity, core.ObjectHelper.toBytes(compacted));
610
+ proofEntity.verifiableStorageId = verifiableCreateResult.id;
611
+ await this._proofStorage.set(proofEntity);
612
+ await this._eventBusComponent?.publish(immutableProofModels.ImmutableProofTopics.ProofCreated, { id: new core.Urn(ImmutableProofService.NAMESPACE, task.payload.proofId).toString() });
552
613
  }
553
- ], undefined, undefined, 2);
554
- if (pendingProofs.entities.length > 0) {
555
- const proofEntity = pendingProofs.entities[0];
556
- const immutableProof = this.proofEntityToModel(proofEntity);
557
- const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
558
- immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
559
- proofEntity.dateCreated = immutableProof.proof.created ?? new Date(Date.now()).toISOString();
560
- const compacted = await dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
561
- proofEntity.immutableStorageId = await this._immutableStorage.store(proofEntity.nodeIdentity, core.ObjectHelper.toBytes(compacted));
562
- await this._proofStorage.set(proofEntity);
563
- }
564
- // If there are still remaining proofs, start the timer again
565
- this._processing = false;
566
- if (pendingProofs.entities.length > 1) {
567
- this.startProcessingProofs();
568
614
  }
569
615
  }
570
616
  /**
571
- * Verify an authentication proof.
617
+ * Verify a proof.
572
618
  * @param id The id of the proof to verify.
573
- * @param proofObject The object to verify as JSON-LD.
619
+ * @param verify Validate the proof.
574
620
  * @returns The result of the verification and any failures.
575
621
  * @throws NotFoundError if the proof is not found.
576
622
  * @internal
577
623
  */
578
- async internalGet(id, proofObject) {
624
+ async internalGet(id, verify) {
579
625
  const urnParsed = core.Urn.fromValidString(id);
580
626
  const proofId = urnParsed.namespaceSpecific(0);
581
627
  const proofEntity = await this._proofStorage.get(proofId);
582
628
  if (core.Is.empty(proofEntity)) {
583
629
  throw new core.NotFoundError(this.CLASS_NAME, "proofNotFound", id);
584
630
  }
585
- let proofModel = await this.proofEntityToModel(proofEntity);
631
+ let proofJsonLd = this.proofEntityToJsonLd(proofEntity);
586
632
  let verified = false;
587
633
  let failure = immutableProofModels.ImmutableProofFailure.NotIssued;
588
- if (core.Is.stringValue(proofEntity.immutableStorageId)) {
634
+ if (core.Is.stringValue(proofEntity.verifiableStorageId)) {
589
635
  failure = immutableProofModels.ImmutableProofFailure.ProofMissing;
590
- const immutableData = await this._immutableStorage.get(proofEntity.immutableStorageId);
591
- if (core.Is.uint8Array(immutableData)) {
592
- proofModel = core.ObjectHelper.fromBytes(immutableData);
593
- if (core.Is.object(proofModel.proof) && core.Is.object(proofObject)) {
594
- if (proofModel.proof.cryptosuite !== standardsW3cDid.DidCryptoSuites.EdDSAJcs2022) {
636
+ const immutableResult = await this._verifiableStorage.get(proofEntity.verifiableStorageId);
637
+ if (core.Is.uint8Array(immutableResult.data)) {
638
+ proofJsonLd = core.ObjectHelper.fromBytes(immutableResult.data);
639
+ const unsecureDocument = core.ObjectHelper.clone(proofJsonLd);
640
+ proofJsonLd.immutableReceipt = immutableResult.receipt;
641
+ proofJsonLd.verifiableStorageId = proofEntity.verifiableStorageId;
642
+ // As we are adding the receipt to the data we update the JSON-LD context
643
+ const receiptContext = immutableResult.receipt["@context"];
644
+ if (!core.Is.empty(receiptContext)) {
645
+ proofJsonLd["@context"] = dataJsonLd.JsonLdProcessor.combineContexts(proofJsonLd["@context"], receiptContext);
646
+ }
647
+ if (verify && core.Is.object(proofJsonLd.proof)) {
648
+ if (proofJsonLd.proof.cryptosuite !== standardsW3cDid.DidCryptoSuites.EdDSAJcs2022) {
595
649
  failure = immutableProofModels.ImmutableProofFailure.CryptoSuiteMismatch;
596
650
  }
597
- else if (proofModel.proof.type !== standardsW3cDid.DidTypes.DataIntegrityProof) {
651
+ else if (proofJsonLd.proof.type !== standardsW3cDid.ProofTypes.DataIntegrityProof) {
598
652
  failure = immutableProofModels.ImmutableProofFailure.ProofTypeMismatch;
599
653
  }
600
654
  else {
601
- const hashData = await this.generateHashData(proofEntity.nodeIdentity, proofModel);
602
- const isVerified = await this._identityConnector.verifyProof(hashData, proofModel.proof);
655
+ const isVerified = await this._identityConnector.verifyProof(unsecureDocument, proofJsonLd.proof);
603
656
  if (isVerified) {
604
657
  verified = true;
605
658
  failure = undefined;
@@ -612,98 +665,13 @@ class ImmutableProofService {
612
665
  }
613
666
  }
614
667
  return {
615
- immutableProof: proofModel,
668
+ immutableProof: proofJsonLd,
616
669
  verified,
617
670
  failure
618
671
  };
619
672
  }
620
- /**
621
- * Generate the hash data for the proof.
622
- * Conforms to https://www.w3.org/TR/vc-di-eddsa/#create-proof-eddsa-jcs-2022
623
- * @param nodeIdentity The node identity to use for vault operations.
624
- * @param immutableProof The immutable proof to generate the hash data for.
625
- * @returns The hash data.
626
- * @internal
627
- */
628
- async generateHashData(nodeIdentity, immutableProof) {
629
- const canonicalDocument = core.JsonHelper.canonicalize(core.ObjectHelper.omit(immutableProof, ["proof"]));
630
- const proofConfigKey = await this._vaultConnector.getKey(`${nodeIdentity}/${this._proofConfigKeyId}`);
631
- const proofConfigHash = crypto.Sha256.sum256(proofConfigKey.privateKey);
632
- const transformedDocumentHash = crypto.Sha256.sum256(core.Converter.utf8ToBytes(canonicalDocument));
633
- const hashData = new Uint8Array(proofConfigHash.length + transformedDocumentHash.length);
634
- hashData.set(proofConfigHash);
635
- hashData.set(transformedDocumentHash, proofConfigHash.length);
636
- return hashData;
637
- }
638
673
  }
639
674
 
640
- // Copyright 2024 IOTA Stiftung.
641
- // SPDX-License-Identifier: Apache-2.0.
642
- /**
643
- * Class describing the immutable proof.
644
- */
645
- exports.ImmutableProof = class ImmutableProof {
646
- /**
647
- * The id of the proof.
648
- */
649
- id;
650
- /**
651
- * The identity of the node which controls the proof.
652
- */
653
- nodeIdentity;
654
- /**
655
- * The identity of the user which created the proof.
656
- */
657
- userIdentity;
658
- /**
659
- * The date/time of when the proof was created.
660
- */
661
- dateCreated;
662
- /**
663
- * The associated id for the item.
664
- */
665
- proofObjectId;
666
- /**
667
- * The associated hash for the item.
668
- */
669
- proofObjectHash;
670
- /**
671
- * The immutable storage id.
672
- */
673
- immutableStorageId;
674
- };
675
- __decorate([
676
- entity.property({ type: "string", isPrimary: true }),
677
- __metadata("design:type", String)
678
- ], exports.ImmutableProof.prototype, "id", void 0);
679
- __decorate([
680
- entity.property({ type: "string" }),
681
- __metadata("design:type", String)
682
- ], exports.ImmutableProof.prototype, "nodeIdentity", void 0);
683
- __decorate([
684
- entity.property({ type: "string" }),
685
- __metadata("design:type", String)
686
- ], exports.ImmutableProof.prototype, "userIdentity", void 0);
687
- __decorate([
688
- entity.property({ type: "string", format: "date-time", sortDirection: entity.SortDirection.Descending }),
689
- __metadata("design:type", String)
690
- ], exports.ImmutableProof.prototype, "dateCreated", void 0);
691
- __decorate([
692
- entity.property({ type: "string" }),
693
- __metadata("design:type", String)
694
- ], exports.ImmutableProof.prototype, "proofObjectId", void 0);
695
- __decorate([
696
- entity.property({ type: "string" }),
697
- __metadata("design:type", String)
698
- ], exports.ImmutableProof.prototype, "proofObjectHash", void 0);
699
- __decorate([
700
- entity.property({ type: "string" }),
701
- __metadata("design:type", String)
702
- ], exports.ImmutableProof.prototype, "immutableStorageId", void 0);
703
- exports.ImmutableProof = __decorate([
704
- entity.entity()
705
- ], exports.ImmutableProof);
706
-
707
675
  const restEntryPoints = [
708
676
  {
709
677
  name: "immutable-proof",