@twin.org/immutable-proof-service 0.0.1-next.6 → 0.0.1-next.8

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.
@@ -4,13 +4,14 @@ var core = require('@twin.org/core');
4
4
  var immutableProofModels = require('@twin.org/immutable-proof-models');
5
5
  var standardsW3cDid = require('@twin.org/standards-w3c-did');
6
6
  var web = require('@twin.org/web');
7
+ var backgroundTaskModels = require('@twin.org/background-task-models');
7
8
  var crypto = require('@twin.org/crypto');
8
9
  var dataJsonLd = require('@twin.org/data-json-ld');
9
- var entity = require('@twin.org/entity');
10
10
  var entityStorageModels = require('@twin.org/entity-storage-models');
11
11
  var identityModels = require('@twin.org/identity-models');
12
12
  var immutableStorageModels = require('@twin.org/immutable-storage-models');
13
13
  var vaultModels = require('@twin.org/vault-models');
14
+ var entity = require('@twin.org/entity');
14
15
 
15
16
  /**
16
17
  * The source used when communicating about these routes.
@@ -330,20 +331,20 @@ class ImmutableProofService {
330
331
  */
331
332
  _immutableStorage;
332
333
  /**
333
- * The assertion method id to use for the proofs.
334
+ * The background task connector.
334
335
  * @internal
335
336
  */
336
- _assertionMethodId;
337
+ _backgroundTaskConnector;
337
338
  /**
338
- * The proof config key id to use for the proofs.
339
+ * The assertion method id to use for the proofs.
339
340
  * @internal
340
341
  */
341
- _proofConfigKeyId;
342
+ _assertionMethodId;
342
343
  /**
343
- * Are we currently processing proofs.
344
+ * The proof hash key id to use for the proofs.
344
345
  * @internal
345
346
  */
346
- _processing;
347
+ _proofHashKeyId;
347
348
  /**
348
349
  * Create a new instance of ImmutableProofService.
349
350
  * @param options The dependencies for the immutable proof connector.
@@ -352,16 +353,18 @@ class ImmutableProofService {
352
353
  * @param options.immutableProofEntityStorageType The entity storage for proofs, defaults to "immutable-proof".
353
354
  * @param options.immutableStorageType The immutable storage, defaults to "immutable-storage".
354
355
  * @param options.identityConnectorType The identity connector type, defaults to "identity".
356
+ * @param options.backgroundTaskConnectorType The background task connector type, defaults to "background-task".
355
357
  */
356
358
  constructor(options) {
357
359
  this._vaultConnector = vaultModels.VaultConnectorFactory.get(options?.vaultConnectorType ?? "vault");
358
360
  this._proofStorage = entityStorageModels.EntityStorageConnectorFactory.get(options?.immutableProofEntityStorageType ?? core.StringHelper.kebabCase("ImmutableProof"));
359
361
  this._immutableStorage = immutableStorageModels.ImmutableStorageConnectorFactory.get(options?.immutableStorageType ?? "immutable-storage");
360
362
  this._identityConnector = identityModels.IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
363
+ this._backgroundTaskConnector = backgroundTaskModels.BackgroundTaskConnectorFactory.get(options?.backgroundTaskConnectorType ?? "background-task");
361
364
  this._config = options?.config ?? {};
362
- this._assertionMethodId = this._config.assertionMethodId ?? "immutable-proof";
363
- this._proofConfigKeyId = this._config.proofConfigKeyId ?? "immutable-proof";
364
- this._processing = false;
365
+ this._assertionMethodId = this._config.assertionMethodId ?? "immutable-proof-assertion";
366
+ this._proofHashKeyId = this._config.proofHashKeyId ?? "immutable-proof-hash";
367
+ this._backgroundTaskConnector.registerHandler("immutable-proof", async (proof) => this.processProof(proof));
365
368
  }
366
369
  /**
367
370
  * Create a new authentication proof.
@@ -391,7 +394,7 @@ class ImmutableProofService {
391
394
  proofObjectHash: core.Converter.bytesToBase64(hash)
392
395
  };
393
396
  await this._proofStorage.set(proofEntity);
394
- this.startProcessingProofs(0);
397
+ await this._backgroundTaskConnector.create("immutable-proof", proofEntity);
395
398
  return new core.Urn(ImmutableProofService.NAMESPACE, id).toString();
396
399
  }
397
400
  catch (error) {
@@ -517,66 +520,26 @@ class ImmutableProofService {
517
520
  return model;
518
521
  }
519
522
  /**
520
- * Start processing proofs.
521
- * @param interval The interval to process proofs.
522
- * @returns Nothing.
523
+ * Process a proof.
524
+ * @param proofEntity The proof entity to process.
523
525
  * @internal
524
526
  */
525
- startProcessingProofs(interval) {
526
- if (!this._processing) {
527
- this._processing = true;
528
- setTimeout(async () => {
529
- await this.processProofs();
530
- }, interval);
531
- }
532
- }
533
- /**
534
- * Process the proofs.
535
- * @internal
536
- */
537
- async processProofs() {
538
- let remainingProofs = 0;
539
- try {
540
- // Get the oldest pending proof, plus one more, we can then determine whether to
541
- // trigger another process after this one
542
- const pendingProofs = await this._proofStorage.query({
543
- property: "immutableStorageId",
544
- comparison: entity.ComparisonOperator.Equals,
545
- value: undefined
546
- }, [
547
- {
548
- property: "dateCreated",
549
- sortDirection: entity.SortDirection.Ascending
550
- }
551
- ], undefined, undefined, 2);
552
- remainingProofs = pendingProofs.entities.length;
553
- if (remainingProofs > 0) {
554
- const proofEntity = pendingProofs.entities[0];
555
- const immutableProof = this.proofEntityToJsonLd(proofEntity);
556
- const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
557
- // As we are adding the proof to the data we update its context
558
- immutableProof["@context"] = [
559
- immutableProofModels.ImmutableProofTypes.ContextRoot,
560
- standardsW3cDid.DidContexts.ContextVCDataIntegrity
561
- ];
562
- immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
563
- if (core.Is.stringValue(immutableProof.proof.created)) {
564
- proofEntity.dateCreated = immutableProof.proof.created;
565
- }
566
- const compacted = await dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
567
- const immutableStoreResult = await this._immutableStorage.store(proofEntity.nodeIdentity, core.ObjectHelper.toBytes(compacted));
568
- proofEntity.immutableStorageId = immutableStoreResult.id;
569
- await this._proofStorage.set(proofEntity);
570
- remainingProofs--;
571
- }
572
- }
573
- finally {
574
- // If there are still remaining proofs, start the timer again
575
- this._processing = false;
576
- if (remainingProofs > 0) {
577
- this.startProcessingProofs(100);
578
- }
527
+ async processProof(proofEntity) {
528
+ const immutableProof = this.proofEntityToJsonLd(proofEntity);
529
+ const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
530
+ // As we are adding the proof to the data we update its context
531
+ immutableProof["@context"] = [
532
+ immutableProofModels.ImmutableProofTypes.ContextRoot,
533
+ standardsW3cDid.DidContexts.ContextVCDataIntegrity
534
+ ];
535
+ immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
536
+ if (core.Is.stringValue(immutableProof.proof.created)) {
537
+ proofEntity.dateCreated = immutableProof.proof.created;
579
538
  }
539
+ const compacted = await dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
540
+ const immutableStoreResult = await this._immutableStorage.store(proofEntity.nodeIdentity, core.ObjectHelper.toBytes(compacted));
541
+ proofEntity.immutableStorageId = immutableStoreResult.id;
542
+ await this._proofStorage.set(proofEntity);
580
543
  }
581
544
  /**
582
545
  * Verify an authentication proof.
@@ -642,17 +605,17 @@ class ImmutableProofService {
642
605
  * @internal
643
606
  */
644
607
  async generateHashData(nodeIdentity, immutableProof) {
645
- // We hash the data for the proof with the proof or immutable receipt for the proof
608
+ // We hash the data for the proof without the the proof or immutable receipt for the proof
646
609
  // without these objects we can simplify the context
647
610
  const object = core.ObjectHelper.omit(immutableProof, ["proof", "immutableReceipt"]);
648
611
  object["@context"] = immutableProofModels.ImmutableProofTypes.ContextRoot;
649
612
  const canonicalDocument = core.JsonHelper.canonicalize(object);
650
- const proofConfigKey = await this._vaultConnector.getKey(`${nodeIdentity}/${this._proofConfigKeyId}`);
651
- const proofConfigHash = crypto.Sha256.sum256(proofConfigKey.privateKey);
613
+ const proofKey = await this._vaultConnector.getKey(`${nodeIdentity}/${this._proofHashKeyId}`);
614
+ const proofHash = crypto.Sha256.sum256(proofKey.privateKey);
652
615
  const transformedDocumentHash = crypto.Sha256.sum256(core.Converter.utf8ToBytes(canonicalDocument));
653
- const hashData = new Uint8Array(proofConfigHash.length + transformedDocumentHash.length);
654
- hashData.set(proofConfigHash);
655
- hashData.set(transformedDocumentHash, proofConfigHash.length);
616
+ const hashData = new Uint8Array(proofHash.length + transformedDocumentHash.length);
617
+ hashData.set(proofHash);
618
+ hashData.set(transformedDocumentHash, proofHash.length);
656
619
  return hashData;
657
620
  }
658
621
  }
@@ -2,13 +2,14 @@ import { Guards, ComponentFactory, StringHelper, Validation, Converter, RandomHe
2
2
  import { ImmutableProofTypes, ImmutableProofFailure } from '@twin.org/immutable-proof-models';
3
3
  import { DidContexts, DidTypes, DidCryptoSuites } from '@twin.org/standards-w3c-did';
4
4
  import { HttpStatusCode, HeaderTypes, MimeTypes } from '@twin.org/web';
5
+ import { BackgroundTaskConnectorFactory } from '@twin.org/background-task-models';
5
6
  import { Blake2b, Sha256 } from '@twin.org/crypto';
6
7
  import { JsonLdHelper, JsonLdProcessor } from '@twin.org/data-json-ld';
7
- import { ComparisonOperator, SortDirection, property, entity, EntitySchemaFactory, EntitySchemaHelper } from '@twin.org/entity';
8
8
  import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
9
9
  import { IdentityConnectorFactory } from '@twin.org/identity-models';
10
10
  import { ImmutableStorageConnectorFactory, ImmutableStorageTypes } from '@twin.org/immutable-storage-models';
11
11
  import { VaultConnectorFactory } from '@twin.org/vault-models';
12
+ import { property, SortDirection, entity, EntitySchemaFactory, EntitySchemaHelper } from '@twin.org/entity';
12
13
 
13
14
  /**
14
15
  * The source used when communicating about these routes.
@@ -328,20 +329,20 @@ class ImmutableProofService {
328
329
  */
329
330
  _immutableStorage;
330
331
  /**
331
- * The assertion method id to use for the proofs.
332
+ * The background task connector.
332
333
  * @internal
333
334
  */
334
- _assertionMethodId;
335
+ _backgroundTaskConnector;
335
336
  /**
336
- * The proof config key id to use for the proofs.
337
+ * The assertion method id to use for the proofs.
337
338
  * @internal
338
339
  */
339
- _proofConfigKeyId;
340
+ _assertionMethodId;
340
341
  /**
341
- * Are we currently processing proofs.
342
+ * The proof hash key id to use for the proofs.
342
343
  * @internal
343
344
  */
344
- _processing;
345
+ _proofHashKeyId;
345
346
  /**
346
347
  * Create a new instance of ImmutableProofService.
347
348
  * @param options The dependencies for the immutable proof connector.
@@ -350,16 +351,18 @@ class ImmutableProofService {
350
351
  * @param options.immutableProofEntityStorageType The entity storage for proofs, defaults to "immutable-proof".
351
352
  * @param options.immutableStorageType The immutable storage, defaults to "immutable-storage".
352
353
  * @param options.identityConnectorType The identity connector type, defaults to "identity".
354
+ * @param options.backgroundTaskConnectorType The background task connector type, defaults to "background-task".
353
355
  */
354
356
  constructor(options) {
355
357
  this._vaultConnector = VaultConnectorFactory.get(options?.vaultConnectorType ?? "vault");
356
358
  this._proofStorage = EntityStorageConnectorFactory.get(options?.immutableProofEntityStorageType ?? StringHelper.kebabCase("ImmutableProof"));
357
359
  this._immutableStorage = ImmutableStorageConnectorFactory.get(options?.immutableStorageType ?? "immutable-storage");
358
360
  this._identityConnector = IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
361
+ this._backgroundTaskConnector = BackgroundTaskConnectorFactory.get(options?.backgroundTaskConnectorType ?? "background-task");
359
362
  this._config = options?.config ?? {};
360
- this._assertionMethodId = this._config.assertionMethodId ?? "immutable-proof";
361
- this._proofConfigKeyId = this._config.proofConfigKeyId ?? "immutable-proof";
362
- this._processing = false;
363
+ this._assertionMethodId = this._config.assertionMethodId ?? "immutable-proof-assertion";
364
+ this._proofHashKeyId = this._config.proofHashKeyId ?? "immutable-proof-hash";
365
+ this._backgroundTaskConnector.registerHandler("immutable-proof", async (proof) => this.processProof(proof));
363
366
  }
364
367
  /**
365
368
  * Create a new authentication proof.
@@ -389,7 +392,7 @@ class ImmutableProofService {
389
392
  proofObjectHash: Converter.bytesToBase64(hash)
390
393
  };
391
394
  await this._proofStorage.set(proofEntity);
392
- this.startProcessingProofs(0);
395
+ await this._backgroundTaskConnector.create("immutable-proof", proofEntity);
393
396
  return new Urn(ImmutableProofService.NAMESPACE, id).toString();
394
397
  }
395
398
  catch (error) {
@@ -515,66 +518,26 @@ class ImmutableProofService {
515
518
  return model;
516
519
  }
517
520
  /**
518
- * Start processing proofs.
519
- * @param interval The interval to process proofs.
520
- * @returns Nothing.
521
+ * Process a proof.
522
+ * @param proofEntity The proof entity to process.
521
523
  * @internal
522
524
  */
523
- startProcessingProofs(interval) {
524
- if (!this._processing) {
525
- this._processing = true;
526
- setTimeout(async () => {
527
- await this.processProofs();
528
- }, interval);
529
- }
530
- }
531
- /**
532
- * Process the proofs.
533
- * @internal
534
- */
535
- async processProofs() {
536
- let remainingProofs = 0;
537
- try {
538
- // Get the oldest pending proof, plus one more, we can then determine whether to
539
- // trigger another process after this one
540
- const pendingProofs = await this._proofStorage.query({
541
- property: "immutableStorageId",
542
- comparison: ComparisonOperator.Equals,
543
- value: undefined
544
- }, [
545
- {
546
- property: "dateCreated",
547
- sortDirection: SortDirection.Ascending
548
- }
549
- ], undefined, undefined, 2);
550
- remainingProofs = pendingProofs.entities.length;
551
- if (remainingProofs > 0) {
552
- const proofEntity = pendingProofs.entities[0];
553
- const immutableProof = this.proofEntityToJsonLd(proofEntity);
554
- const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
555
- // As we are adding the proof to the data we update its context
556
- immutableProof["@context"] = [
557
- ImmutableProofTypes.ContextRoot,
558
- DidContexts.ContextVCDataIntegrity
559
- ];
560
- immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
561
- if (Is.stringValue(immutableProof.proof.created)) {
562
- proofEntity.dateCreated = immutableProof.proof.created;
563
- }
564
- const compacted = await JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
565
- const immutableStoreResult = await this._immutableStorage.store(proofEntity.nodeIdentity, ObjectHelper.toBytes(compacted));
566
- proofEntity.immutableStorageId = immutableStoreResult.id;
567
- await this._proofStorage.set(proofEntity);
568
- remainingProofs--;
569
- }
570
- }
571
- finally {
572
- // If there are still remaining proofs, start the timer again
573
- this._processing = false;
574
- if (remainingProofs > 0) {
575
- this.startProcessingProofs(100);
576
- }
525
+ async processProof(proofEntity) {
526
+ const immutableProof = this.proofEntityToJsonLd(proofEntity);
527
+ const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
528
+ // As we are adding the proof to the data we update its context
529
+ immutableProof["@context"] = [
530
+ ImmutableProofTypes.ContextRoot,
531
+ DidContexts.ContextVCDataIntegrity
532
+ ];
533
+ immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
534
+ if (Is.stringValue(immutableProof.proof.created)) {
535
+ proofEntity.dateCreated = immutableProof.proof.created;
577
536
  }
537
+ const compacted = await JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
538
+ const immutableStoreResult = await this._immutableStorage.store(proofEntity.nodeIdentity, ObjectHelper.toBytes(compacted));
539
+ proofEntity.immutableStorageId = immutableStoreResult.id;
540
+ await this._proofStorage.set(proofEntity);
578
541
  }
579
542
  /**
580
543
  * Verify an authentication proof.
@@ -640,17 +603,17 @@ class ImmutableProofService {
640
603
  * @internal
641
604
  */
642
605
  async generateHashData(nodeIdentity, immutableProof) {
643
- // We hash the data for the proof with the proof or immutable receipt for the proof
606
+ // We hash the data for the proof without the the proof or immutable receipt for the proof
644
607
  // without these objects we can simplify the context
645
608
  const object = ObjectHelper.omit(immutableProof, ["proof", "immutableReceipt"]);
646
609
  object["@context"] = ImmutableProofTypes.ContextRoot;
647
610
  const canonicalDocument = JsonHelper.canonicalize(object);
648
- const proofConfigKey = await this._vaultConnector.getKey(`${nodeIdentity}/${this._proofConfigKeyId}`);
649
- const proofConfigHash = Sha256.sum256(proofConfigKey.privateKey);
611
+ const proofKey = await this._vaultConnector.getKey(`${nodeIdentity}/${this._proofHashKeyId}`);
612
+ const proofHash = Sha256.sum256(proofKey.privateKey);
650
613
  const transformedDocumentHash = Sha256.sum256(Converter.utf8ToBytes(canonicalDocument));
651
- const hashData = new Uint8Array(proofConfigHash.length + transformedDocumentHash.length);
652
- hashData.set(proofConfigHash);
653
- hashData.set(transformedDocumentHash, proofConfigHash.length);
614
+ const hashData = new Uint8Array(proofHash.length + transformedDocumentHash.length);
615
+ hashData.set(proofHash);
616
+ hashData.set(transformedDocumentHash, proofHash.length);
654
617
  return hashData;
655
618
  }
656
619
  }
@@ -21,13 +21,15 @@ export declare class ImmutableProofService implements IImmutableProofComponent {
21
21
  * @param options.immutableProofEntityStorageType The entity storage for proofs, defaults to "immutable-proof".
22
22
  * @param options.immutableStorageType The immutable storage, defaults to "immutable-storage".
23
23
  * @param options.identityConnectorType The identity connector type, defaults to "identity".
24
+ * @param options.backgroundTaskConnectorType The background task connector type, defaults to "background-task".
24
25
  */
25
26
  constructor(options?: {
26
27
  vaultConnectorType?: string;
27
28
  immutableProofEntityStorageType?: string;
28
29
  immutableStorageType?: string;
29
- config?: IImmutableProofServiceConfig;
30
30
  identityConnectorType?: string;
31
+ backgroundTaskConnectorType?: string;
32
+ config?: IImmutableProofServiceConfig;
31
33
  });
32
34
  /**
33
35
  * Create a new authentication proof.
@@ -4,12 +4,12 @@
4
4
  export interface IImmutableProofServiceConfig {
5
5
  /**
6
6
  * The assertion method id to use for the stream.
7
- * @default immutable-proof
7
+ * @default immutable-proof-assertion
8
8
  */
9
9
  assertionMethodId?: string;
10
10
  /**
11
- * The key to use in the proof config.
12
- * @default immutable-proof
11
+ * The key to use in the proof hash.
12
+ * @default immutable-proof-hash
13
13
  */
14
- proofConfigKeyId?: string;
14
+ proofHashKeyId?: string;
15
15
  }
package/docs/changelog.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # @twin.org/immutable-proof-service - Changelog
2
2
 
3
- ## v0.0.1-next.6
3
+ ## v0.0.1-next.8
4
4
 
5
5
  - Initial Release
@@ -32,14 +32,18 @@ The entity storage for proofs, defaults to "immutable-proof".
32
32
 
33
33
  The immutable storage, defaults to "immutable-storage".
34
34
 
35
- • **options.config?**: [`IImmutableProofServiceConfig`](../interfaces/IImmutableProofServiceConfig.md)
36
-
37
- The configuration for the connector.
38
-
39
35
  • **options.identityConnectorType?**: `string`
40
36
 
41
37
  The identity connector type, defaults to "identity".
42
38
 
39
+ • **options.backgroundTaskConnectorType?**: `string`
40
+
41
+ The background task connector type, defaults to "background-task".
42
+
43
+ • **options.config?**: [`IImmutableProofServiceConfig`](../interfaces/IImmutableProofServiceConfig.md)
44
+
45
+ The configuration for the connector.
46
+
43
47
  #### Returns
44
48
 
45
49
  [`ImmutableProofService`](ImmutableProofService.md)
@@ -13,19 +13,19 @@ The assertion method id to use for the stream.
13
13
  #### Default
14
14
 
15
15
  ```ts
16
- immutable-proof
16
+ immutable-proof-assertion
17
17
  ```
18
18
 
19
19
  ***
20
20
 
21
- ### proofConfigKeyId?
21
+ ### proofHashKeyId?
22
22
 
23
- > `optional` **proofConfigKeyId**: `string`
23
+ > `optional` **proofHashKeyId**: `string`
24
24
 
25
- The key to use in the proof config.
25
+ The key to use in the proof hash.
26
26
 
27
27
  #### Default
28
28
 
29
29
  ```ts
30
- immutable-proof
30
+ immutable-proof-hash
31
31
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/immutable-proof-service",
3
- "version": "0.0.1-next.6",
3
+ "version": "0.0.1-next.8",
4
4
  "description": "Immutable proof contract implementation and REST endpoint definitions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,6 +15,7 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@twin.org/api-models": "next",
18
+ "@twin.org/background-task-models": "next",
18
19
  "@twin.org/core": "next",
19
20
  "@twin.org/crypto": "next",
20
21
  "@twin.org/data-json-ld": "next",
@@ -22,7 +23,7 @@
22
23
  "@twin.org/entity": "next",
23
24
  "@twin.org/entity-storage-models": "next",
24
25
  "@twin.org/identity-models": "next",
25
- "@twin.org/immutable-proof-models": "0.0.1-next.6",
26
+ "@twin.org/immutable-proof-models": "0.0.1-next.8",
26
27
  "@twin.org/immutable-storage-models": "next",
27
28
  "@twin.org/nameof": "next",
28
29
  "@twin.org/standards-w3c-did": "next",