@twin.org/node-core 0.0.2-next.15 → 0.0.2-next.17

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 (42) hide show
  1. package/dist/cjs/index.cjs +360 -160
  2. package/dist/esm/index.mjs +351 -164
  3. package/dist/types/builders/engineEnvBuilder.d.ts +1 -1
  4. package/dist/types/builders/engineServerEnvBuilder.d.ts +2 -2
  5. package/dist/types/builders/extensionsBuilder.d.ts +31 -0
  6. package/dist/types/defaults.d.ts +6 -0
  7. package/dist/types/index.d.ts +4 -0
  8. package/dist/types/models/IEngineEnvironmentVariables.d.ts +60 -18
  9. package/dist/types/models/INodeEngineConfig.d.ts +6 -0
  10. package/dist/types/models/INodeOptions.d.ts +2 -1
  11. package/dist/types/models/nodeExtensionMethods.d.ts +22 -0
  12. package/dist/types/node.d.ts +2 -2
  13. package/dist/types/server.d.ts +4 -2
  14. package/dist/types/utils.d.ts +18 -0
  15. package/docs/changelog.md +15 -0
  16. package/docs/reference/functions/buildConfiguration.md +2 -2
  17. package/docs/reference/functions/buildEngineConfiguration.md +2 -2
  18. package/docs/reference/functions/buildEngineServerConfiguration.md +3 -3
  19. package/docs/reference/functions/directoryExists.md +19 -0
  20. package/docs/reference/functions/extensionsConfiguration.md +25 -0
  21. package/docs/reference/functions/extensionsInitialiseEngine.md +25 -0
  22. package/docs/reference/functions/extensionsInitialiseEngineServer.md +31 -0
  23. package/docs/reference/functions/getFiles.md +19 -0
  24. package/docs/reference/functions/getSubFolders.md +19 -0
  25. package/docs/reference/functions/shutdownExtensions.md +19 -0
  26. package/docs/reference/functions/start.md +4 -4
  27. package/docs/reference/index.md +17 -0
  28. package/docs/reference/interfaces/IEngineEnvironmentVariables.md +118 -26
  29. package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +166 -34
  30. package/docs/reference/interfaces/INodeEngineConfig.md +7 -0
  31. package/docs/reference/interfaces/INodeEnvironmentVariables.md +166 -34
  32. package/docs/reference/interfaces/INodeOptions.md +6 -2
  33. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineMethod.md +18 -0
  34. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineServerMethod.md +24 -0
  35. package/docs/reference/type-aliases/NodeExtensionInitialiseMethod.md +23 -0
  36. package/docs/reference/variables/ATTESTATION_VERIFICATION_METHOD_ID.md +3 -0
  37. package/docs/reference/variables/AUTH_SIGNING_KEY_ID.md +3 -0
  38. package/docs/reference/variables/BLOB_STORAGE_ENCRYPTION_KEY_ID.md +3 -0
  39. package/docs/reference/variables/IMMUTABLE_PROOF_VERIFICATION_METHOD_ID.md +3 -0
  40. package/docs/reference/variables/SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID.md +3 -0
  41. package/docs/reference/variables/VC_AUTHENTICATION_VERIFICATION_METHOD_ID.md +3 -0
  42. package/package.json +13 -2
@@ -1,13 +1,13 @@
1
1
  import { PasswordHelper } from '@twin.org/api-auth-entity-storage-service';
2
- import { I18n, Is, Coerce, Converter, RandomHelper, StringHelper, Urn, GeneralError, ErrorHelper, EnvHelper } from '@twin.org/core';
2
+ import { I18n, Is, Coerce, Converter, RandomHelper, Urn, GeneralError, ErrorHelper, EnvHelper } from '@twin.org/core';
3
3
  import { PasswordGenerator, Bip39 } from '@twin.org/crypto';
4
4
  import { AuthenticationComponentType, InformationComponentType, RestRouteProcessorType, SocketRouteProcessorType, AuthenticationAdminComponentType } from '@twin.org/engine-server-types';
5
- import { WalletConnectorType, IdentityConnectorType, EntityStorageConnectorType, BlobStorageConnectorType, BlobStorageComponentType, VaultConnectorType, DltConfigType, LoggingConnectorType, LoggingComponentType, BackgroundTaskConnectorType, TaskSchedulerComponentType, EventBusConnectorType, EventBusComponentType, TelemetryConnectorType, TelemetryComponentType, MessagingEmailConnectorType, MessagingSmsConnectorType, MessagingPushNotificationConnectorType, MessagingComponentType, FaucetConnectorType, EngineTypeHelper, NftConnectorType, NftComponentType, VerifiableStorageConnectorType, VerifiableStorageComponentType, ImmutableProofComponentType, IdentityComponentType, IdentityResolverConnectorType, IdentityResolverComponentType, IdentityProfileConnectorType, IdentityProfileComponentType, AttestationConnectorType, AttestationComponentType, DataProcessingComponentType, DataConverterConnectorType, DataExtractorConnectorType, AuditableItemGraphComponentType, AuditableItemStreamComponentType, DocumentManagementComponentType, AuthenticationGeneratorComponentType, RightsManagementPapComponentType, RightsManagementPmpComponentType, RightsManagementPipComponentType, RightsManagementPxpComponentType, RightsManagementPdpComponentType, RightsManagementPepComponentType, RightsManagementPnpComponentType, RightsManagementPnapComponentType, RightsManagementDapComponentType, RightsManagementDarpComponentType, SynchronisedStorageComponentType, FederatedCatalogueComponentType, DataSpaceConnectorComponentType } from '@twin.org/engine-types';
5
+ import { WalletConnectorType, IdentityConnectorType, EntityStorageConnectorType, BlobStorageConnectorType, BlobStorageComponentType, VaultConnectorType, DltConfigType, LoggingConnectorType, LoggingComponentType, BackgroundTaskConnectorType, TaskSchedulerComponentType, EventBusConnectorType, EventBusComponentType, TelemetryConnectorType, TelemetryComponentType, MessagingEmailConnectorType, MessagingSmsConnectorType, MessagingPushNotificationConnectorType, MessagingAdminComponentType, MessagingComponentType, FaucetConnectorType, EngineTypeHelper, NftConnectorType, NftComponentType, VerifiableStorageConnectorType, VerifiableStorageComponentType, ImmutableProofComponentType, IdentityComponentType, IdentityResolverConnectorType, IdentityResolverComponentType, IdentityProfileConnectorType, IdentityProfileComponentType, AttestationConnectorType, AttestationComponentType, DataProcessingComponentType, DataConverterConnectorType, DataExtractorConnectorType, AuditableItemGraphComponentType, AuditableItemStreamComponentType, DocumentManagementComponentType, AuthenticationGeneratorComponentType, RightsManagementPapComponentType, RightsManagementPmpComponentType, RightsManagementPipComponentType, RightsManagementPxpComponentType, RightsManagementPdpComponentType, RightsManagementPepComponentType, RightsManagementPnpComponentType, RightsManagementPnapComponentType, RightsManagementDapComponentType, RightsManagementDarpComponentType, SynchronisedStorageComponentType, FederatedCatalogueComponentType, DataSpaceConnectorComponentType } from '@twin.org/engine-types';
6
6
  import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
7
7
  import { IdentityProfileConnectorFactory, IdentityConnectorFactory, IdentityResolverConnectorFactory, DocumentHelper } from '@twin.org/identity-models';
8
8
  import { VaultConnectorFactory, VaultKeyType } from '@twin.org/vault-models';
9
9
  import { WalletConnectorFactory } from '@twin.org/wallet-models';
10
- import { readFile, stat } from 'node:fs/promises';
10
+ import { readFile, stat, readdir } from 'node:fs/promises';
11
11
  import path from 'node:path';
12
12
  import { PolicyNegotiationPointClient, DataAccessPointClient } from '@twin.org/rights-management-rest-client';
13
13
  import { addDefaultRestPaths, addDefaultSocketPaths, EngineServer } from '@twin.org/engine-server';
@@ -17,6 +17,15 @@ import { Engine } from '@twin.org/engine';
17
17
  import { FileStateStorage } from '@twin.org/engine-core';
18
18
  import { EngineCoreFactory } from '@twin.org/engine-models';
19
19
 
20
+ // Copyright 2024 IOTA Stiftung.
21
+ // SPDX-License-Identifier: Apache-2.0.
22
+ const ATTESTATION_VERIFICATION_METHOD_ID = "attestation-assertion";
23
+ const IMMUTABLE_PROOF_VERIFICATION_METHOD_ID = "immutable-proof-assertion";
24
+ const BLOB_STORAGE_ENCRYPTION_KEY_ID = "blob-encryption";
25
+ const SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID = "synchronised-storage-blob-encryption";
26
+ const VC_AUTHENTICATION_VERIFICATION_METHOD_ID = "node-authentication-assertion";
27
+ const AUTH_SIGNING_KEY_ID = "auth-signing";
28
+
20
29
  // Copyright 2024 IOTA Stiftung.
21
30
  // SPDX-License-Identifier: Apache-2.0.
22
31
  /**
@@ -77,6 +86,64 @@ async function fileExists(filename) {
77
86
  return false;
78
87
  }
79
88
  }
89
+ /**
90
+ * Does the specified directory exist.
91
+ * @param directory The directory to check for existence.
92
+ * @returns True if the directory exists.
93
+ */
94
+ async function directoryExists(directory) {
95
+ try {
96
+ const stats = await stat(directory);
97
+ return stats.isDirectory();
98
+ }
99
+ catch {
100
+ return false;
101
+ }
102
+ }
103
+ /**
104
+ * Get the sub folders for the folder.
105
+ * @param directory The directory to get the sub folders.
106
+ * @returns The list of sub folders.
107
+ */
108
+ async function getSubFolders(directory) {
109
+ try {
110
+ const dir = await readdir(directory);
111
+ const folders = [];
112
+ for (const dirEntry of dir) {
113
+ const fullPath = path.join(directory, dirEntry);
114
+ const stats = await stat(fullPath);
115
+ if (stats.isDirectory()) {
116
+ folders.push(fullPath);
117
+ }
118
+ }
119
+ return folders;
120
+ }
121
+ catch {
122
+ return [];
123
+ }
124
+ }
125
+ /**
126
+ * Get the files in the directory.
127
+ * @param directory The directory to get the files from.
128
+ * @returns The list of files in the directory.
129
+ */
130
+ async function getFiles(directory) {
131
+ try {
132
+ const dir = await readdir(directory);
133
+ const files = [];
134
+ for (const dirEntry of dir) {
135
+ const fullPath = path.join(directory, dirEntry);
136
+ const stats = await stat(fullPath);
137
+ if (stats.isFile()) {
138
+ files.push(fullPath);
139
+ }
140
+ }
141
+ return files;
142
+ }
143
+ catch {
144
+ return [];
145
+ }
146
+ }
80
147
  /**
81
148
  * Load the text file.
82
149
  * @param filename The filename of the text file to load.
@@ -130,10 +197,16 @@ async function bootstrap(engineCore, context, envVars) {
130
197
  await bootstrapNodeUser(engineCore, context, envVars, features);
131
198
  await bootstrapAuth(engineCore, context, envVars);
132
199
  await bootstrapBlobEncryption(engineCore, context, envVars);
133
- await addVerificationMethod(engineCore, context, "attestation", envVars.attestationVerificationMethodId);
134
- await addVerificationMethod(engineCore, context, "immutable proof", envVars.immutableProofVerificationMethodId);
200
+ const defaultAttestationConnectorType = engineCore.getRegisteredInstanceTypeOptional("attestationConnector");
201
+ if (!Is.empty(defaultAttestationConnectorType)) {
202
+ await addVerificationMethod(engineCore, context, "attestation", envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID);
203
+ }
204
+ const defaultImmutableProofComponentType = engineCore.getRegisteredInstanceTypeOptional("immutableProofComponent");
205
+ if (!Is.empty(defaultImmutableProofComponentType)) {
206
+ await addVerificationMethod(engineCore, context, "immutable proof", envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID);
207
+ }
135
208
  if (Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
136
- await addVerificationMethod(engineCore, context, "verifiable credential authentication", envVars.vcAuthenticationVerificationMethodId);
209
+ await addVerificationMethod(engineCore, context, "verifiable credential authentication", envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID);
137
210
  }
138
211
  await bootstrapSynchronisedStorage(engineCore, context, envVars);
139
212
  }
@@ -246,7 +319,7 @@ async function finaliseWallet(engineCore, envVars, features, finalIdentity, addr
246
319
  // If we are using entity storage for wallet the identity associated with the
247
320
  // address will be wrong, so fix it
248
321
  if (defaultWalletConnectorType.startsWith(WalletConnectorType.EntityStorage)) {
249
- const walletAddress = EntityStorageConnectorFactory.get(StringHelper.kebabCase("WalletAddress"));
322
+ const walletAddress = EntityStorageConnectorFactory.get("wallet-address");
250
323
  const addr = await walletAddress.get(addresses[0]);
251
324
  if (!Is.empty(addr)) {
252
325
  addr.identity = finalIdentity;
@@ -316,7 +389,7 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
316
389
  const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceType("authenticationComponent");
317
390
  if (defaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&
318
391
  Is.stringValue(context.state.nodeIdentity)) {
319
- const authUserEntityStorage = EntityStorageConnectorFactory.get(StringHelper.kebabCase("AuthenticationUser"));
392
+ const authUserEntityStorage = EntityStorageConnectorFactory.get("authentication-user");
320
393
  const email = envVars.username ?? DEFAULT_NODE_USERNAME;
321
394
  let nodeAdminUser = await authUserEntityStorage.get(email);
322
395
  if (Is.empty(nodeAdminUser)) {
@@ -409,7 +482,7 @@ async function bootstrapBlobEncryption(engineCore, context, envVars, features) {
409
482
  // Create a new key for encrypting blobs
410
483
  const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
411
484
  const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
412
- const keyName = `${context.state.nodeIdentity}/${envVars.blobStorageEncryptionKeyId}`;
485
+ const keyName = `${context.state.nodeIdentity}/${envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID}`;
413
486
  let existingKey;
414
487
  try {
415
488
  existingKey = await vaultConnector.getKey(keyName);
@@ -449,7 +522,7 @@ async function bootstrapAuth(engineCore, context, envVars, features) {
449
522
  // Create a new JWT signing key and a user login for the node
450
523
  const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
451
524
  const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
452
- const keyName = `${context.state.nodeIdentity}/${envVars.authSigningKeyId}`;
525
+ const keyName = `${context.state.nodeIdentity}/${envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID}`;
453
526
  let existingKey;
454
527
  try {
455
528
  existingKey = await vaultConnector.getKey(keyName);
@@ -474,11 +547,11 @@ async function bootstrapAuth(engineCore, context, envVars, features) {
474
547
  async function bootstrapSynchronisedStorage(engineCore, context, envVars, features) {
475
548
  if (Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false) {
476
549
  // If this is a trusted node we need to add the blob encryption key pair
477
- if (Is.stringValue(envVars.synchronisedStorageBlobStorageEncryptionKeyId) &&
478
- Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {
550
+ if (Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {
479
551
  const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
480
552
  const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
481
- const keyName = envVars.synchronisedStorageBlobStorageEncryptionKeyId;
553
+ const keyName = envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
554
+ SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;
482
555
  let existingKey;
483
556
  try {
484
557
  existingKey = await vaultConnector.getKey(keyName);
@@ -540,49 +613,43 @@ async function addVerificationMethod(engineCore, context, verificationMethodTitl
540
613
  * @param envVars The environment variables.
541
614
  * @returns The config for the core.
542
615
  */
543
- function buildEngineConfiguration(envVars) {
616
+ async function buildEngineConfiguration(envVars) {
544
617
  if (Is.stringValue(envVars.storageFileRoot)) {
545
618
  envVars.stateFilename ??= "engine-state.json";
546
619
  envVars.storageFileRoot = path.resolve(envVars.storageFileRoot);
547
620
  envVars.stateFilename = path.join(envVars.storageFileRoot, envVars.stateFilename);
548
621
  }
549
- envVars.attestationVerificationMethodId ??= "attestation-assertion";
550
- envVars.immutableProofVerificationMethodId ??= "immutable-proof-assertion";
551
- envVars.blobStorageEnableEncryption ??= "false";
552
- envVars.blobStorageEncryptionKeyId ??= "blob-encryption";
553
- envVars.synchronisedStorageBlobStorageEncryptionKeyId ??= "synchronised-storage-blob-encryption";
554
- envVars.vcAuthenticationVerificationMethodId ??= "node-authentication-assertion";
555
622
  const coreConfig = {
556
623
  debug: Coerce.boolean(envVars.debug) ?? false,
557
624
  types: {}
558
625
  };
559
- configureEntityStorage(coreConfig, envVars);
560
- configureBlobStorage(coreConfig, envVars);
561
- configureVault(coreConfig, envVars);
562
- configureDlt(coreConfig, envVars);
563
- configureLogging(coreConfig, envVars);
564
- configureBackgroundTask(coreConfig, envVars);
565
- configureTaskScheduler(coreConfig, envVars);
566
- configureEventBus(coreConfig, envVars);
567
- configureTelemetry(coreConfig, envVars);
568
- configureMessaging(coreConfig, envVars);
569
- configureFaucet(coreConfig, envVars);
570
- configureWallet(coreConfig, envVars);
571
- configureNft(coreConfig, envVars);
572
- configureVerifiableStorage(coreConfig, envVars);
573
- configureIdentity(coreConfig, envVars);
574
- configureIdentityResolver(coreConfig, envVars);
575
- configureIdentityProfile(coreConfig, envVars);
576
- configureAttestation(coreConfig, envVars);
577
- configureDataProcessing(coreConfig, envVars);
578
- configureAuditableItemGraph(coreConfig, envVars);
579
- configureAuditableItemStream(coreConfig, envVars);
580
- configureDocumentManagement(coreConfig, envVars);
581
- configureVerifiableCredentialAuthentication(coreConfig, envVars);
582
- configureRightsManagement(coreConfig, envVars);
583
- configureSynchronisedStorage(coreConfig, envVars);
584
- configureFederatedCatalogue(coreConfig, envVars);
585
- configureDataSpaceConnector(coreConfig, envVars);
626
+ await configureEntityStorage(coreConfig, envVars);
627
+ await configureBlobStorage(coreConfig, envVars);
628
+ await configureVault(coreConfig, envVars);
629
+ await configureDlt(coreConfig, envVars);
630
+ await configureLogging(coreConfig, envVars);
631
+ await configureBackgroundTask(coreConfig, envVars);
632
+ await configureTaskScheduler(coreConfig, envVars);
633
+ await configureEventBus(coreConfig, envVars);
634
+ await configureTelemetry(coreConfig, envVars);
635
+ await configureMessaging(coreConfig, envVars);
636
+ await configureFaucet(coreConfig, envVars);
637
+ await configureWallet(coreConfig, envVars);
638
+ await configureNft(coreConfig, envVars);
639
+ await configureVerifiableStorage(coreConfig, envVars);
640
+ await configureIdentity(coreConfig, envVars);
641
+ await configureIdentityResolver(coreConfig, envVars);
642
+ await configureIdentityProfile(coreConfig, envVars);
643
+ await configureAttestation(coreConfig, envVars);
644
+ await configureDataProcessing(coreConfig, envVars);
645
+ await configureAuditableItemGraph(coreConfig, envVars);
646
+ await configureAuditableItemStream(coreConfig, envVars);
647
+ await configureDocumentManagement(coreConfig, envVars);
648
+ await configureVerifiableCredentialAuthentication(coreConfig, envVars);
649
+ await configureRightsManagement(coreConfig, envVars);
650
+ await configureSynchronisedStorage(coreConfig, envVars);
651
+ await configureFederatedCatalogue(coreConfig, envVars);
652
+ await configureDataSpaceConnector(coreConfig, envVars);
586
653
  return coreConfig;
587
654
  }
588
655
  /**
@@ -590,7 +657,7 @@ function buildEngineConfiguration(envVars) {
590
657
  * @param coreConfig The core config.
591
658
  * @param envVars The environment variables.
592
659
  */
593
- function configureEntityStorage(coreConfig, envVars) {
660
+ async function configureEntityStorage(coreConfig, envVars) {
594
661
  coreConfig.types ??= {};
595
662
  coreConfig.types.entityStorageConnector ??= [];
596
663
  const entityStorageConnectorTypes = envVars.entityStorageConnectorType?.split(",") ?? [];
@@ -614,9 +681,10 @@ function configureEntityStorage(coreConfig, envVars) {
614
681
  options: {
615
682
  config: {
616
683
  region: envVars.awsDynamodbRegion ?? "",
617
- accessKeyId: envVars.awsDynamodbAccessKeyId ?? "",
618
- secretAccessKey: envVars.awsDynamodbSecretAccessKey ?? "",
619
- endpoint: envVars.awsDynamodbEndpoint ?? ""
684
+ authMode: envVars.awsDynamodbAuthMode,
685
+ accessKeyId: envVars.awsDynamodbAccessKeyId,
686
+ secretAccessKey: envVars.awsDynamodbSecretAccessKey,
687
+ endpoint: envVars.awsDynamodbEndpoint
620
688
  },
621
689
  tablePrefix: envVars.entityStorageTablePrefix
622
690
  }
@@ -734,7 +802,7 @@ function configureEntityStorage(coreConfig, envVars) {
734
802
  * @param coreConfig The core config.
735
803
  * @param envVars The environment variables.
736
804
  */
737
- function configureBlobStorage(coreConfig, envVars) {
805
+ async function configureBlobStorage(coreConfig, envVars) {
738
806
  coreConfig.types.blobStorageConnector ??= [];
739
807
  const blobStorageConnectorTypes = envVars.blobStorageConnectorType?.split(",") ?? [];
740
808
  if (blobStorageConnectorTypes.includes(BlobStorageConnectorType.Memory)) {
@@ -773,9 +841,10 @@ function configureBlobStorage(coreConfig, envVars) {
773
841
  config: {
774
842
  region: envVars.awsS3Region ?? "",
775
843
  bucketName: envVars.awsS3BucketName ?? "",
776
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
777
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
778
- endpoint: envVars.awsS3Endpoint ?? ""
844
+ authMode: envVars.awsS3AuthMode,
845
+ accessKeyId: envVars.awsS3AccessKeyId,
846
+ secretAccessKey: envVars.awsS3SecretAccessKey,
847
+ endpoint: envVars.awsS3Endpoint
779
848
  },
780
849
  storagePrefix: envVars.blobStoragePrefix
781
850
  }
@@ -832,7 +901,7 @@ function configureBlobStorage(coreConfig, envVars) {
832
901
  options: {
833
902
  config: {
834
903
  vaultKeyId: (envVars.blobStorageEnableEncryption ?? false)
835
- ? envVars.blobStorageEncryptionKeyId
904
+ ? (envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID)
836
905
  : undefined
837
906
  }
838
907
  }
@@ -844,7 +913,7 @@ function configureBlobStorage(coreConfig, envVars) {
844
913
  * @param coreConfig The core config.
845
914
  * @param envVars The environment variables.
846
915
  */
847
- function configureLogging(coreConfig, envVars) {
916
+ async function configureLogging(coreConfig, envVars) {
848
917
  coreConfig.types.loggingConnector ??= [];
849
918
  const loggingConnectors = (envVars.loggingConnector ?? "").split(",");
850
919
  for (const loggingConnector of loggingConnectors) {
@@ -886,7 +955,7 @@ function configureLogging(coreConfig, envVars) {
886
955
  * @param coreConfig The core config.
887
956
  * @param envVars The environment variables.
888
957
  */
889
- function configureVault(coreConfig, envVars) {
958
+ async function configureVault(coreConfig, envVars) {
890
959
  coreConfig.types.vaultConnector ??= [];
891
960
  if (envVars.vaultConnector === VaultConnectorType.EntityStorage) {
892
961
  coreConfig.types.vaultConnector.push({
@@ -910,7 +979,7 @@ function configureVault(coreConfig, envVars) {
910
979
  * @param coreConfig The core config.
911
980
  * @param envVars The environment variables.
912
981
  */
913
- function configureBackgroundTask(coreConfig, envVars) {
982
+ async function configureBackgroundTask(coreConfig, envVars) {
914
983
  coreConfig.types.backgroundTaskConnector ??= [];
915
984
  if (envVars.backgroundTaskConnector === BackgroundTaskConnectorType.EntityStorage) {
916
985
  coreConfig.types.backgroundTaskConnector.push({
@@ -923,7 +992,7 @@ function configureBackgroundTask(coreConfig, envVars) {
923
992
  * @param coreConfig The core config.
924
993
  * @param envVars The environment variables.
925
994
  */
926
- function configureEventBus(coreConfig, envVars) {
995
+ async function configureEventBus(coreConfig, envVars) {
927
996
  coreConfig.types.eventBusConnector ??= [];
928
997
  if (envVars.eventBusConnector === EventBusConnectorType.Local) {
929
998
  coreConfig.types.eventBusConnector.push({
@@ -940,7 +1009,7 @@ function configureEventBus(coreConfig, envVars) {
940
1009
  * @param coreConfig The core config.
941
1010
  * @param envVars The environment variables.
942
1011
  */
943
- function configureTelemetry(coreConfig, envVars) {
1012
+ async function configureTelemetry(coreConfig, envVars) {
944
1013
  coreConfig.types.telemetryConnector ??= [];
945
1014
  if (envVars.telemetryConnector === TelemetryConnectorType.EntityStorage) {
946
1015
  coreConfig.types.telemetryConnector.push({
@@ -957,71 +1026,84 @@ function configureTelemetry(coreConfig, envVars) {
957
1026
  * @param coreConfig The core config.
958
1027
  * @param envVars The environment variables.
959
1028
  */
960
- function configureMessaging(coreConfig, envVars) {
961
- coreConfig.types.messagingEmailConnector ??= [];
962
- coreConfig.types.messagingSmsConnector ??= [];
963
- coreConfig.types.messagingPushNotificationConnector ??= [];
964
- if (envVars.messagingEmailConnector === MessagingEmailConnectorType.EntityStorage) {
965
- coreConfig.types.messagingEmailConnector.push({
966
- type: MessagingEmailConnectorType.EntityStorage
967
- });
968
- }
969
- else if (envVars.messagingEmailConnector === MessagingEmailConnectorType.Aws) {
970
- coreConfig.types.messagingEmailConnector.push({
971
- type: MessagingEmailConnectorType.Aws,
972
- options: {
973
- config: {
974
- region: envVars.awsS3Region ?? "",
975
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
976
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
977
- endpoint: envVars.awsS3Endpoint ?? ""
1029
+ async function configureMessaging(coreConfig, envVars) {
1030
+ if (Coerce.boolean(envVars.messagingEnabled) ?? false) {
1031
+ coreConfig.types.messagingEmailConnector ??= [];
1032
+ coreConfig.types.messagingSmsConnector ??= [];
1033
+ coreConfig.types.messagingPushNotificationConnector ??= [];
1034
+ if (envVars.messagingEmailConnector === MessagingEmailConnectorType.EntityStorage) {
1035
+ coreConfig.types.messagingEmailConnector.push({
1036
+ type: MessagingEmailConnectorType.EntityStorage
1037
+ });
1038
+ }
1039
+ else if (envVars.messagingEmailConnector === MessagingEmailConnectorType.Aws) {
1040
+ coreConfig.types.messagingEmailConnector.push({
1041
+ type: MessagingEmailConnectorType.Aws,
1042
+ options: {
1043
+ config: {
1044
+ region: envVars.awsSesRegion ?? "",
1045
+ authMode: envVars.awsSesAuthMode,
1046
+ accessKeyId: envVars.awsSesAccessKeyId,
1047
+ secretAccessKey: envVars.awsSesSecretAccessKey,
1048
+ endpoint: envVars.awsSesEndpoint
1049
+ }
978
1050
  }
979
- }
980
- });
981
- }
982
- if (envVars.messagingSmsConnector === MessagingSmsConnectorType.EntityStorage) {
983
- coreConfig.types.messagingSmsConnector.push({
984
- type: MessagingSmsConnectorType.EntityStorage
985
- });
986
- }
987
- else if (envVars.messagingSmsConnector === MessagingSmsConnectorType.Aws) {
988
- coreConfig.types.messagingSmsConnector.push({
989
- type: MessagingSmsConnectorType.Aws,
990
- options: {
991
- config: {
992
- region: envVars.awsS3Region ?? "",
993
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
994
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
995
- endpoint: envVars.awsS3Endpoint ?? ""
1051
+ });
1052
+ }
1053
+ if (envVars.messagingSmsConnector === MessagingSmsConnectorType.EntityStorage) {
1054
+ coreConfig.types.messagingSmsConnector.push({
1055
+ type: MessagingSmsConnectorType.EntityStorage
1056
+ });
1057
+ }
1058
+ else if (envVars.messagingSmsConnector === MessagingSmsConnectorType.Aws) {
1059
+ coreConfig.types.messagingSmsConnector.push({
1060
+ type: MessagingSmsConnectorType.Aws,
1061
+ options: {
1062
+ config: {
1063
+ region: envVars.awsSesRegion ?? "",
1064
+ authMode: envVars.awsSesAuthMode,
1065
+ accessKeyId: envVars.awsSesAccessKeyId,
1066
+ secretAccessKey: envVars.awsSesSecretAccessKey,
1067
+ endpoint: envVars.awsSesEndpoint
1068
+ }
996
1069
  }
997
- }
998
- });
999
- }
1000
- if (envVars.messagingPushNotificationConnector ===
1001
- MessagingPushNotificationConnectorType.EntityStorage) {
1002
- coreConfig.types.messagingPushNotificationConnector.push({
1003
- type: MessagingPushNotificationConnectorType.EntityStorage
1004
- });
1005
- }
1006
- else if (envVars.messagingPushNotificationConnector === MessagingPushNotificationConnectorType.Aws) {
1007
- coreConfig.types.messagingPushNotificationConnector.push({
1008
- type: MessagingPushNotificationConnectorType.Aws,
1070
+ });
1071
+ }
1072
+ if (envVars.messagingPushNotificationConnector ===
1073
+ MessagingPushNotificationConnectorType.EntityStorage) {
1074
+ coreConfig.types.messagingPushNotificationConnector.push({
1075
+ type: MessagingPushNotificationConnectorType.EntityStorage
1076
+ });
1077
+ }
1078
+ else if (envVars.messagingPushNotificationConnector === MessagingPushNotificationConnectorType.Aws) {
1079
+ coreConfig.types.messagingPushNotificationConnector.push({
1080
+ type: MessagingPushNotificationConnectorType.Aws,
1081
+ options: {
1082
+ config: {
1083
+ region: envVars.awsSesRegion ?? "",
1084
+ authMode: envVars.awsSesAuthMode,
1085
+ accessKeyId: envVars.awsSesAccessKeyId,
1086
+ secretAccessKey: envVars.awsSesSecretAccessKey,
1087
+ endpoint: envVars.awsSesEndpoint,
1088
+ applicationsSettings: Is.json(envVars.awsMessagingPushNotificationApplications)
1089
+ ? JSON.parse(envVars.awsMessagingPushNotificationApplications)
1090
+ : []
1091
+ }
1092
+ }
1093
+ });
1094
+ }
1095
+ const templates = Is.arrayValue(envVars.messagingTemplates)
1096
+ ? envVars.messagingTemplates
1097
+ : undefined;
1098
+ coreConfig.types.messagingAdminComponent ??= [];
1099
+ coreConfig.types.messagingAdminComponent.push({
1100
+ type: MessagingAdminComponentType.Service,
1009
1101
  options: {
1010
1102
  config: {
1011
- region: envVars.awsS3Region ?? "",
1012
- accessKeyId: envVars.awsS3AccessKeyId ?? "",
1013
- secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
1014
- endpoint: envVars.awsS3Endpoint ?? "",
1015
- applicationsSettings: Is.json(envVars.awsMessagingPushNotificationApplications)
1016
- ? JSON.parse(envVars.awsMessagingPushNotificationApplications)
1017
- : []
1103
+ templates
1018
1104
  }
1019
1105
  }
1020
1106
  });
1021
- }
1022
- if (coreConfig.types.messagingEmailConnector.length > 0 ||
1023
- coreConfig.types.messagingSmsConnector.length > 0 ||
1024
- coreConfig.types.messagingPushNotificationConnector.length > 0) {
1025
1107
  coreConfig.types.messagingComponent ??= [];
1026
1108
  coreConfig.types.messagingComponent.push({ type: MessagingComponentType.Service });
1027
1109
  }
@@ -1031,7 +1113,7 @@ function configureMessaging(coreConfig, envVars) {
1031
1113
  * @param coreConfig The core config.
1032
1114
  * @param envVars The environment variables.
1033
1115
  */
1034
- function configureFaucet(coreConfig, envVars) {
1116
+ async function configureFaucet(coreConfig, envVars) {
1035
1117
  coreConfig.types.faucetConnector ??= [];
1036
1118
  if (envVars.faucetConnector === FaucetConnectorType.EntityStorage) {
1037
1119
  coreConfig.types.faucetConnector.push({
@@ -1057,7 +1139,7 @@ function configureFaucet(coreConfig, envVars) {
1057
1139
  * @param coreConfig The core config.
1058
1140
  * @param envVars The environment variables.
1059
1141
  */
1060
- function configureWallet(coreConfig, envVars) {
1142
+ async function configureWallet(coreConfig, envVars) {
1061
1143
  coreConfig.types.walletConnector ??= [];
1062
1144
  if (envVars.walletConnector === WalletConnectorType.EntityStorage) {
1063
1145
  coreConfig.types.walletConnector.push({
@@ -1079,7 +1161,7 @@ function configureWallet(coreConfig, envVars) {
1079
1161
  * @param coreConfig The core config.
1080
1162
  * @param envVars The environment variables.
1081
1163
  */
1082
- function configureNft(coreConfig, envVars) {
1164
+ async function configureNft(coreConfig, envVars) {
1083
1165
  coreConfig.types.nftConnector ??= [];
1084
1166
  if (envVars.nftConnector === NftConnectorType.EntityStorage) {
1085
1167
  coreConfig.types.nftConnector.push({
@@ -1105,7 +1187,7 @@ function configureNft(coreConfig, envVars) {
1105
1187
  * @param coreConfig The core config.
1106
1188
  * @param envVars The environment variables.
1107
1189
  */
1108
- function configureVerifiableStorage(coreConfig, envVars) {
1190
+ async function configureVerifiableStorage(coreConfig, envVars) {
1109
1191
  coreConfig.types.verifiableStorageConnector ??= [];
1110
1192
  if (envVars.verifiableStorageConnector === VerifiableStorageConnectorType.EntityStorage) {
1111
1193
  coreConfig.types.verifiableStorageConnector.push({
@@ -1131,7 +1213,7 @@ function configureVerifiableStorage(coreConfig, envVars) {
1131
1213
  type: ImmutableProofComponentType.Service,
1132
1214
  options: {
1133
1215
  config: {
1134
- verificationMethodId: envVars.immutableProofVerificationMethodId
1216
+ verificationMethodId: envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID
1135
1217
  }
1136
1218
  }
1137
1219
  });
@@ -1142,7 +1224,7 @@ function configureVerifiableStorage(coreConfig, envVars) {
1142
1224
  * @param coreConfig The core config.
1143
1225
  * @param envVars The environment variables.
1144
1226
  */
1145
- function configureIdentity(coreConfig, envVars) {
1227
+ async function configureIdentity(coreConfig, envVars) {
1146
1228
  coreConfig.types.identityConnector ??= [];
1147
1229
  if (envVars.identityConnector === IdentityConnectorType.EntityStorage) {
1148
1230
  coreConfig.types.identityConnector.push({
@@ -1168,7 +1250,7 @@ function configureIdentity(coreConfig, envVars) {
1168
1250
  * @param coreConfig The core config.
1169
1251
  * @param envVars The environment variables.
1170
1252
  */
1171
- function configureIdentityResolver(coreConfig, envVars) {
1253
+ async function configureIdentityResolver(coreConfig, envVars) {
1172
1254
  coreConfig.types.identityResolverConnector ??= [];
1173
1255
  if (envVars.identityResolverConnector === IdentityResolverConnectorType.EntityStorage) {
1174
1256
  coreConfig.types.identityResolverConnector.push({
@@ -1206,7 +1288,7 @@ function configureIdentityResolver(coreConfig, envVars) {
1206
1288
  * @param coreConfig The core config.
1207
1289
  * @param envVars The environment variables.
1208
1290
  */
1209
- function configureIdentityProfile(coreConfig, envVars) {
1291
+ async function configureIdentityProfile(coreConfig, envVars) {
1210
1292
  coreConfig.types.identityProfileConnector ??= [];
1211
1293
  if (envVars.identityProfileConnector === IdentityConnectorType.EntityStorage) {
1212
1294
  coreConfig.types.identityProfileConnector.push({
@@ -1223,7 +1305,7 @@ function configureIdentityProfile(coreConfig, envVars) {
1223
1305
  * @param coreConfig The core config.
1224
1306
  * @param envVars The environment variables.
1225
1307
  */
1226
- function configureAttestation(coreConfig, envVars) {
1308
+ async function configureAttestation(coreConfig, envVars) {
1227
1309
  coreConfig.types.attestationConnector ??= [];
1228
1310
  if (envVars.attestationConnector === AttestationConnectorType.Nft) {
1229
1311
  coreConfig.types.attestationConnector.push({
@@ -1236,7 +1318,7 @@ function configureAttestation(coreConfig, envVars) {
1236
1318
  type: AttestationComponentType.Service,
1237
1319
  options: {
1238
1320
  config: {
1239
- verificationMethodId: envVars.attestationVerificationMethodId
1321
+ verificationMethodId: envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID
1240
1322
  }
1241
1323
  }
1242
1324
  });
@@ -1247,7 +1329,7 @@ function configureAttestation(coreConfig, envVars) {
1247
1329
  * @param coreConfig The core config.
1248
1330
  * @param envVars The environment variables.
1249
1331
  */
1250
- function configureAuditableItemGraph(coreConfig, envVars) {
1332
+ async function configureAuditableItemGraph(coreConfig, envVars) {
1251
1333
  if (Coerce.boolean(envVars.auditableItemGraphEnabled) ?? false) {
1252
1334
  coreConfig.types.auditableItemGraphComponent ??= [];
1253
1335
  coreConfig.types.auditableItemGraphComponent.push({
@@ -1260,7 +1342,7 @@ function configureAuditableItemGraph(coreConfig, envVars) {
1260
1342
  * @param coreConfig The core config.
1261
1343
  * @param envVars The environment variables.
1262
1344
  */
1263
- function configureAuditableItemStream(coreConfig, envVars) {
1345
+ async function configureAuditableItemStream(coreConfig, envVars) {
1264
1346
  if (Coerce.boolean(envVars.auditableItemStreamEnabled) ?? false) {
1265
1347
  coreConfig.types.auditableItemStreamComponent ??= [];
1266
1348
  coreConfig.types.auditableItemStreamComponent.push({
@@ -1273,7 +1355,7 @@ function configureAuditableItemStream(coreConfig, envVars) {
1273
1355
  * @param coreConfig The core config.
1274
1356
  * @param envVars The environment variables.
1275
1357
  */
1276
- function configureDataProcessing(coreConfig, envVars) {
1358
+ async function configureDataProcessing(coreConfig, envVars) {
1277
1359
  if (Coerce.boolean(envVars.dataProcessingEnabled) ?? false) {
1278
1360
  coreConfig.types.dataProcessingComponent ??= [];
1279
1361
  coreConfig.types.dataProcessingComponent.push({ type: DataProcessingComponentType.Service });
@@ -1307,7 +1389,7 @@ function configureDataProcessing(coreConfig, envVars) {
1307
1389
  * @param coreConfig The core config.
1308
1390
  * @param envVars The environment variables.
1309
1391
  */
1310
- function configureDocumentManagement(coreConfig, envVars) {
1392
+ async function configureDocumentManagement(coreConfig, envVars) {
1311
1393
  if (Coerce.boolean(envVars.documentManagementEnabled) ?? false) {
1312
1394
  coreConfig.types.documentManagementComponent ??= [];
1313
1395
  coreConfig.types.documentManagementComponent.push({
@@ -1320,14 +1402,16 @@ function configureDocumentManagement(coreConfig, envVars) {
1320
1402
  * @param coreConfig The core config.
1321
1403
  * @param envVars The environment variables.
1322
1404
  */
1323
- function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
1405
+ async function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
1324
1406
  if (Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
1325
1407
  // Can only perform VC authentication if identity component is available
1326
1408
  coreConfig.types.authenticationGeneratorComponent ??= [];
1327
1409
  coreConfig.types.authenticationGeneratorComponent.push({
1328
1410
  type: AuthenticationGeneratorComponentType.VerifiableCredential,
1329
1411
  options: {
1330
- config: { verificationMethodId: envVars.vcAuthenticationVerificationMethodId ?? "" }
1412
+ config: {
1413
+ verificationMethodId: envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID
1414
+ }
1331
1415
  },
1332
1416
  features: ["verifiable-credential"]
1333
1417
  });
@@ -1338,7 +1422,7 @@ function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
1338
1422
  * @param coreConfig The core config.
1339
1423
  * @param envVars The environment variables.
1340
1424
  */
1341
- function configureRightsManagement(coreConfig, envVars) {
1425
+ async function configureRightsManagement(coreConfig, envVars) {
1342
1426
  if (Coerce.boolean(envVars.rightsManagementEnabled) ?? false) {
1343
1427
  coreConfig.types.rightsManagementPapComponent ??= [];
1344
1428
  coreConfig.types.rightsManagementPapComponent.push({
@@ -1427,7 +1511,7 @@ function configureRightsManagement(coreConfig, envVars) {
1427
1511
  * @param coreConfig The core config.
1428
1512
  * @param envVars The environment variables.
1429
1513
  */
1430
- function configureTaskScheduler(coreConfig, envVars) {
1514
+ async function configureTaskScheduler(coreConfig, envVars) {
1431
1515
  if (Coerce.boolean(envVars.taskSchedulerEnabled) ?? false) {
1432
1516
  coreConfig.types.taskSchedulerComponent ??= [];
1433
1517
  coreConfig.types.taskSchedulerComponent.push({
@@ -1440,7 +1524,7 @@ function configureTaskScheduler(coreConfig, envVars) {
1440
1524
  * @param coreConfig The core config.
1441
1525
  * @param envVars The environment variables.
1442
1526
  */
1443
- function configureSynchronisedStorage(coreConfig, envVars) {
1527
+ async function configureSynchronisedStorage(coreConfig, envVars) {
1444
1528
  if (Is.arrayValue(coreConfig.types.identityResolverComponent) &&
1445
1529
  (Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false)) {
1446
1530
  // Check if the config provides a custom verifiable storage key id
@@ -1455,7 +1539,8 @@ function configureSynchronisedStorage(coreConfig, envVars) {
1455
1539
  options: {
1456
1540
  config: {
1457
1541
  verifiableStorageKeyId: verifiableStorageKeyId ?? "",
1458
- blobStorageEncryptionKeyId: envVars.synchronisedStorageBlobStorageEncryptionKeyId,
1542
+ blobStorageEncryptionKeyId: envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
1543
+ SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID,
1459
1544
  entityUpdateIntervalMinutes: Coerce.number(envVars.synchronisedStorageEntityUpdateIntervalMinutes),
1460
1545
  consolidationIntervalMinutes: Coerce.number(envVars.synchronisedStorageConsolidationIntervalMinutes),
1461
1546
  consolidationBatchSize: Coerce.number(envVars.synchronisedStorageConsolidationBatchSize),
@@ -1482,7 +1567,7 @@ function configureSynchronisedStorage(coreConfig, envVars) {
1482
1567
  * @param coreConfig The core config.
1483
1568
  * @param envVars The environment variables.
1484
1569
  */
1485
- function configureFederatedCatalogue(coreConfig, envVars) {
1570
+ async function configureFederatedCatalogue(coreConfig, envVars) {
1486
1571
  if (Coerce.boolean(envVars.federatedCatalogueEnabled) ?? false) {
1487
1572
  coreConfig.types.federatedCatalogueComponent ??= [];
1488
1573
  coreConfig.types.federatedCatalogueComponent.push({
@@ -1501,16 +1586,15 @@ function configureFederatedCatalogue(coreConfig, envVars) {
1501
1586
  * @param coreConfig The core config.
1502
1587
  * @param envVars The environment variables.
1503
1588
  */
1504
- function configureDataSpaceConnector(coreConfig, envVars) {
1589
+ async function configureDataSpaceConnector(coreConfig, envVars) {
1505
1590
  if (Coerce.boolean(envVars.dataSpaceConnectorEnabled) ?? false) {
1506
1591
  coreConfig.types.dataSpaceConnectorComponent ??= [];
1507
1592
  coreConfig.types.dataSpaceConnectorComponent.push({
1508
1593
  type: DataSpaceConnectorComponentType.Service,
1509
1594
  options: {
1510
1595
  config: {
1511
- dataSpaceConnectorAppDescriptors: Is.arrayValue(envVars.dataSpaceConnectorApps)
1512
- ? envVars.dataSpaceConnectorApps
1513
- : undefined
1596
+ retainActivityLogsFor: Coerce.number(envVars.dataSpaceConnectorRetainActivityLogsFor),
1597
+ activityLogsCleanUpInterval: Coerce.number(envVars.dataSpaceConnectorActivityLogsCleanUpInterval)
1514
1598
  }
1515
1599
  }
1516
1600
  });
@@ -1521,7 +1605,7 @@ function configureDataSpaceConnector(coreConfig, envVars) {
1521
1605
  * @param coreConfig The core config.
1522
1606
  * @param envVars The environment variables.
1523
1607
  */
1524
- function configureDlt(coreConfig, envVars) {
1608
+ async function configureDlt(coreConfig, envVars) {
1525
1609
  // Create centralized DLT configuration for IOTA if essential IOTA variables are set
1526
1610
  if (Is.stringValue(envVars.iotaNodeEndpoint) && Is.stringValue(envVars.iotaNetwork)) {
1527
1611
  coreConfig.types.dltConfig ??= [];
@@ -1556,10 +1640,9 @@ function configureDlt(coreConfig, envVars) {
1556
1640
  * @param serverInfo The server information.
1557
1641
  * @param openApiSpecPath The path to the open api spec.
1558
1642
  * @param favIconPath The path to the favicon.
1559
- * @returns The the config for the core and the server.
1643
+ * @returns The config for the core and the server.
1560
1644
  */
1561
- function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath, favIconPath) {
1562
- envVars.authSigningKeyId ??= "auth-signing";
1645
+ async function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath, favIconPath) {
1563
1646
  const webServerOptions = {
1564
1647
  port: Coerce.number(envVars.port),
1565
1648
  host: Coerce.string(envVars.host),
@@ -1675,7 +1758,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1675
1758
  type: AuthenticationComponentType.EntityStorage,
1676
1759
  options: {
1677
1760
  config: {
1678
- signingKeyName: envVars.authSigningKeyId
1761
+ signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
1679
1762
  }
1680
1763
  }
1681
1764
  });
@@ -1683,7 +1766,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1683
1766
  type: RestRouteProcessorType.AuthHeader,
1684
1767
  options: {
1685
1768
  config: {
1686
- signingKeyName: envVars.authSigningKeyId
1769
+ signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
1687
1770
  }
1688
1771
  }
1689
1772
  });
@@ -1691,7 +1774,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1691
1774
  type: SocketRouteProcessorType.AuthHeader,
1692
1775
  options: {
1693
1776
  config: {
1694
- signingKeyName: envVars.authSigningKeyId
1777
+ signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
1695
1778
  }
1696
1779
  }
1697
1780
  });
@@ -1709,17 +1792,111 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
1709
1792
  return serverConfig;
1710
1793
  }
1711
1794
 
1795
+ // Copyright 2024 IOTA Stiftung.
1796
+ // SPDX-License-Identifier: Apache-2.0.
1797
+ /* eslint-disable no-console */
1798
+ /**
1799
+ * Handles the configuration of the extensions.
1800
+ * @param envVars The environment variables for the node.
1801
+ * @param nodeEngineConfig The node engine config.
1802
+ * @returns The config for the core and the server.
1803
+ */
1804
+ async function extensionsConfiguration(envVars, nodeEngineConfig) {
1805
+ if (Is.stringValue(envVars.extensions)) {
1806
+ const extensions = envVars.extensions.split(",");
1807
+ for (const extension of extensions) {
1808
+ let initialiseConfigMethod;
1809
+ try {
1810
+ console.info(`Loading extension "${extension}"`);
1811
+ initialiseConfigMethod = await ModuleHelper.getModuleMethod(extension, "extensionInitialise");
1812
+ }
1813
+ catch (err) {
1814
+ console.error(`Failed to load extension "${extension}":`, err);
1815
+ }
1816
+ if (Is.function(initialiseConfigMethod)) {
1817
+ await initialiseConfigMethod(envVars, nodeEngineConfig);
1818
+ }
1819
+ }
1820
+ }
1821
+ return nodeEngineConfig;
1822
+ }
1823
+ /**
1824
+ * Handles the initialisation of the extensions when the engine has been constructed.
1825
+ * @param envVars The environment variables for the node.
1826
+ * @param engineCore The engine core instance.
1827
+ * @returns Nothing.
1828
+ */
1829
+ async function extensionsInitialiseEngine(envVars, engineCore) {
1830
+ if (Is.stringValue(envVars.extensions)) {
1831
+ const extensions = envVars.extensions.split(",");
1832
+ for (const extension of extensions) {
1833
+ let initialiseEngineMethod;
1834
+ try {
1835
+ initialiseEngineMethod =
1836
+ await ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngine");
1837
+ }
1838
+ catch { }
1839
+ if (Is.function(initialiseEngineMethod)) {
1840
+ await initialiseEngineMethod(engineCore);
1841
+ }
1842
+ }
1843
+ }
1844
+ }
1845
+ /**
1846
+ * Handles the initialisation of the extensions when the engine server has been constructed.
1847
+ * @param envVars The environment variables for the node.
1848
+ * @param engineCore The engine core instance.
1849
+ * @param engineServer The engine server instance.
1850
+ * @returns Nothing.
1851
+ */
1852
+ async function extensionsInitialiseEngineServer(envVars, engineCore, engineServer) {
1853
+ if (Is.stringValue(envVars.extensions)) {
1854
+ const extensions = envVars.extensions.split(",");
1855
+ for (const extension of extensions) {
1856
+ let initialiseEngineServerMethod;
1857
+ try {
1858
+ initialiseEngineServerMethod =
1859
+ await ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngineServer");
1860
+ }
1861
+ catch { }
1862
+ if (Is.function(initialiseEngineServerMethod)) {
1863
+ await initialiseEngineServerMethod(engineCore, engineServer);
1864
+ }
1865
+ }
1866
+ }
1867
+ }
1868
+ /**
1869
+ * Handles the shutdown of the extensions.
1870
+ * @param envVars The environment variables for the node.
1871
+ * @returns Nothing.
1872
+ */
1873
+ async function shutdownExtensions(envVars) {
1874
+ if (Is.stringValue(envVars.extensions)) {
1875
+ const extensions = envVars.extensions.split(",");
1876
+ for (const extension of extensions) {
1877
+ let shutdownMethod;
1878
+ try {
1879
+ shutdownMethod = await ModuleHelper.getModuleMethod(extension, "extensionShutdown");
1880
+ }
1881
+ catch { }
1882
+ if (Is.function(shutdownMethod)) {
1883
+ await shutdownMethod();
1884
+ }
1885
+ }
1886
+ }
1887
+ }
1888
+
1712
1889
  // Copyright 2024 IOTA Stiftung.
1713
1890
  // SPDX-License-Identifier: Apache-2.0.
1714
1891
  /* eslint-disable no-console */
1715
1892
  /**
1716
1893
  * Start the engine server.
1717
1894
  * @param nodeOptions Optional run options for the engine server.
1718
- * @param engineServerConfig The configuration for the engine server.
1895
+ * @param nodeEngineConfig The configuration for the engine server.
1719
1896
  * @param envVars The environment variables.
1720
1897
  * @returns The engine server.
1721
1898
  */
1722
- async function start(nodeOptions, engineServerConfig, envVars) {
1899
+ async function start(nodeOptions, nodeEngineConfig, envVars) {
1723
1900
  const entityStorageConnectorType = envVars.entityStorageConnectorType?.split(",") ?? [];
1724
1901
  const blobStorageConnectorType = envVars.blobStorageConnectorType?.split(",") ?? [];
1725
1902
  // If the blob storage or entity storage is configured with file connectors
@@ -1734,7 +1911,7 @@ async function start(nodeOptions, engineServerConfig, envVars) {
1734
1911
  }
1735
1912
  // Create the engine instance using file state storage unless one is configured in options
1736
1913
  const engine = new Engine({
1737
- config: engineServerConfig,
1914
+ config: nodeEngineConfig,
1738
1915
  stateStorage: nodeOptions?.stateStorage ?? new FileStateStorage(envVars.stateFilename ?? ""),
1739
1916
  customBootstrap: async (core, engineContext) => bootstrap(core, engineContext, envVars)
1740
1917
  });
@@ -1745,11 +1922,13 @@ async function start(nodeOptions, engineServerConfig, envVars) {
1745
1922
  console.info("Extending Engine");
1746
1923
  await nodeOptions.extendEngine(engine);
1747
1924
  }
1925
+ await extensionsInitialiseEngine(envVars, engine);
1748
1926
  // Extend the engine server.
1749
1927
  if (Is.function(nodeOptions?.extendEngineServer)) {
1750
1928
  console.info("Extending Engine Server");
1751
1929
  await nodeOptions?.extendEngineServer(server);
1752
1930
  }
1931
+ await extensionsInitialiseEngineServer(envVars, engine, server);
1753
1932
  // Need to register the engine with the factory so that background tasks
1754
1933
  // can clone it to spawn new instances.
1755
1934
  EngineCoreFactory.register("engine", () => engine);
@@ -1758,7 +1937,11 @@ async function start(nodeOptions, engineServerConfig, envVars) {
1758
1937
  if (canContinue) {
1759
1938
  return {
1760
1939
  engine,
1761
- server
1940
+ server,
1941
+ shutdown: async () => {
1942
+ await server.stop();
1943
+ await shutdownExtensions(envVars);
1944
+ }
1762
1945
  };
1763
1946
  }
1764
1947
  }
@@ -1776,7 +1959,7 @@ async function run(nodeOptions) {
1776
1959
  nodeOptions ??= {};
1777
1960
  const serverInfo = {
1778
1961
  name: nodeOptions?.serverName ?? "TWIN Node Server",
1779
- version: nodeOptions?.serverVersion ?? "0.0.2-next.15" // x-release-please-version
1962
+ version: nodeOptions?.serverVersion ?? "0.0.2-next.17" // x-release-please-version
1780
1963
  };
1781
1964
  console.log(`\u001B[4m🌩️ ${serverInfo.name} v${serverInfo.version}\u001B[24m\n`);
1782
1965
  if (!Is.stringValue(nodeOptions?.executionDirectory)) {
@@ -1807,13 +1990,16 @@ async function run(nodeOptions) {
1807
1990
  nodeOptions.envPrefix ??= "TWIN_NODE_";
1808
1991
  console.info("Environment Prefix:", nodeOptions.envPrefix);
1809
1992
  overrideModuleImport(nodeOptions.executionDirectory ?? "");
1810
- const { engineServerConfig, nodeEnvVars: envVars } = await buildConfiguration(process.env, nodeOptions, serverInfo);
1993
+ const { nodeEngineConfig, nodeEnvVars: envVars } = await buildConfiguration(
1994
+ // This is the only location in the code base that should access process.env directly
1995
+ // eslint-disable-next-line no-restricted-syntax
1996
+ process.env, nodeOptions, serverInfo);
1811
1997
  console.info();
1812
- const startResult = await start(nodeOptions, engineServerConfig, envVars);
1998
+ const startResult = await start(nodeOptions, nodeEngineConfig, envVars);
1813
1999
  if (!Is.empty(startResult)) {
1814
2000
  for (const signal of ["SIGHUP", "SIGINT", "SIGTERM"]) {
1815
2001
  process.on(signal, async () => {
1816
- await startResult.server.stop();
2002
+ await startResult.shutdown();
1817
2003
  });
1818
2004
  }
1819
2005
  }
@@ -1879,8 +2065,8 @@ async function buildConfiguration(processEnv, options, serverInfo) {
1879
2065
  await options.extendEnvVars(envVars);
1880
2066
  }
1881
2067
  // Build the engine configuration from the environment variables.
1882
- const coreConfig = buildEngineConfiguration(envVars);
1883
- const engineServerConfig = buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile, options?.favIconFile);
2068
+ const coreConfig = await buildEngineConfiguration(envVars);
2069
+ const engineServerConfig = await buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile, options?.favIconFile);
1884
2070
  // Merge any custom configuration provided in the options.
1885
2071
  if (Is.arrayValue(options?.configFilenames)) {
1886
2072
  for (const configFile of options.configFilenames) {
@@ -1897,9 +2083,10 @@ async function buildConfiguration(processEnv, options, serverInfo) {
1897
2083
  // Merge any custom configuration provided in the options.
1898
2084
  if (Is.function(options?.extendConfig)) {
1899
2085
  console.info("Extending Configuration");
1900
- await options.extendConfig(engineServerConfig);
2086
+ await options.extendConfig(envVars, engineServerConfig);
1901
2087
  }
1902
- return { engineServerConfig, nodeEnvVars: envVars };
2088
+ const nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);
2089
+ return { nodeEngineConfig, nodeEnvVars: envVars };
1903
2090
  }
1904
2091
  /**
1905
2092
  * Override module imports to use local files where possible.
@@ -1936,4 +2123,4 @@ function overrideModuleImport(executionDirectory) {
1936
2123
  });
1937
2124
  }
1938
2125
 
1939
- export { NodeFeatures, bootstrap, bootstrapAuth, bootstrapBlobEncryption, bootstrapImmutableProofMethod, bootstrapNodeIdentity, bootstrapNodeUser, bootstrapSynchronisedStorage, buildConfiguration, buildEngineConfiguration, buildEngineServerConfiguration, fileExists, getExecutionDirectory, getFeatures, initialiseLocales, loadJsonFile, loadTextFile, overrideModuleImport, run, start };
2126
+ export { ATTESTATION_VERIFICATION_METHOD_ID, AUTH_SIGNING_KEY_ID, BLOB_STORAGE_ENCRYPTION_KEY_ID, IMMUTABLE_PROOF_VERIFICATION_METHOD_ID, NodeFeatures, SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID, VC_AUTHENTICATION_VERIFICATION_METHOD_ID, bootstrap, bootstrapAuth, bootstrapBlobEncryption, bootstrapImmutableProofMethod, bootstrapNodeIdentity, bootstrapNodeUser, bootstrapSynchronisedStorage, buildConfiguration, buildEngineConfiguration, buildEngineServerConfiguration, directoryExists, extensionsConfiguration, extensionsInitialiseEngine, extensionsInitialiseEngineServer, fileExists, getExecutionDirectory, getFeatures, getFiles, getSubFolders, initialiseLocales, loadJsonFile, loadTextFile, overrideModuleImport, run, shutdownExtensions, start };