@twin.org/node-core 0.0.2-next.2 → 0.0.2-next.20
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.
- package/dist/cjs/index.cjs +863 -391
- package/dist/esm/index.mjs +851 -394
- package/dist/types/bootstrap.d.ts +9 -9
- package/dist/types/builders/engineEnvBuilder.d.ts +1 -1
- package/dist/types/builders/engineServerEnvBuilder.d.ts +3 -2
- package/dist/types/builders/extensionsBuilder.d.ts +32 -0
- package/dist/types/defaults.d.ts +6 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/models/IEngineEnvironmentVariables.d.ts +188 -24
- package/dist/types/models/IEngineServerEnvironmentVariables.d.ts +12 -3
- package/dist/types/models/INodeEngineConfig.d.ts +6 -0
- package/dist/types/models/INodeEnvironmentVariables.d.ts +1 -2
- package/dist/types/models/INodeOptions.d.ts +6 -1
- package/dist/types/models/nodeExtensionMethods.d.ts +27 -0
- package/dist/types/models/nodeFeatures.d.ts +4 -0
- package/dist/types/node.d.ts +7 -2
- package/dist/types/server.d.ts +4 -2
- package/dist/types/utils.d.ts +24 -0
- package/docs/changelog.md +131 -0
- package/docs/reference/functions/{bootstrapAttestationMethod.md → bootstrapSynchronisedStorage.md} +3 -3
- package/docs/reference/functions/buildConfiguration.md +2 -2
- package/docs/reference/functions/buildEngineConfiguration.md +2 -2
- package/docs/reference/functions/buildEngineServerConfiguration.md +9 -3
- package/docs/reference/functions/directoryExists.md +19 -0
- package/docs/reference/functions/extensionsConfiguration.md +25 -0
- package/docs/reference/functions/extensionsInitialiseEngine.md +25 -0
- package/docs/reference/functions/extensionsInitialiseEngineServer.md +31 -0
- package/docs/reference/functions/getFiles.md +19 -0
- package/docs/reference/functions/getSubFolders.md +19 -0
- package/docs/reference/functions/loadTextFile.md +19 -0
- package/docs/reference/functions/overrideModuleImport.md +17 -0
- package/docs/reference/functions/shutdownExtensions.md +25 -0
- package/docs/reference/functions/start.md +4 -4
- package/docs/reference/index.md +21 -1
- package/docs/reference/interfaces/IEngineEnvironmentVariables.md +374 -36
- package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +1673 -5
- package/docs/reference/interfaces/INodeEngineConfig.md +7 -0
- package/docs/reference/interfaces/INodeEnvironmentVariables.md +643 -137
- package/docs/reference/interfaces/INodeOptions.md +14 -2
- package/docs/reference/type-aliases/NodeExtensionInitialiseEngineMethod.md +18 -0
- package/docs/reference/type-aliases/NodeExtensionInitialiseEngineServerMethod.md +24 -0
- package/docs/reference/type-aliases/NodeExtensionInitialiseMethod.md +23 -0
- package/docs/reference/type-aliases/NodeExtensionShutdownMethod.md +10 -0
- package/docs/reference/variables/ATTESTATION_VERIFICATION_METHOD_ID.md +3 -0
- package/docs/reference/variables/AUTH_SIGNING_KEY_ID.md +3 -0
- package/docs/reference/variables/BLOB_STORAGE_ENCRYPTION_KEY_ID.md +3 -0
- package/docs/reference/variables/IMMUTABLE_PROOF_VERIFICATION_METHOD_ID.md +3 -0
- package/docs/reference/variables/NodeFeatures.md +7 -1
- package/docs/reference/variables/SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID.md +3 -0
- package/docs/reference/variables/VC_AUTHENTICATION_VERIFICATION_METHOD_ID.md +3 -0
- package/locales/en.json +15 -6
- package/package.json +18 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
import { PasswordHelper } from '@twin.org/api-auth-entity-storage-service';
|
|
2
|
-
import { I18n, Is, Converter, RandomHelper,
|
|
2
|
+
import { I18n, Is, Coerce, Converter, RandomHelper, Urn, GeneralError, EnvHelper } from '@twin.org/core';
|
|
3
3
|
import { PasswordGenerator, Bip39 } from '@twin.org/crypto';
|
|
4
|
-
import {
|
|
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, 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';
|
|
5
6
|
import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
|
|
6
7
|
import { IdentityProfileConnectorFactory, IdentityConnectorFactory, IdentityResolverConnectorFactory, DocumentHelper } from '@twin.org/identity-models';
|
|
7
8
|
import { VaultConnectorFactory, VaultKeyType } from '@twin.org/vault-models';
|
|
8
9
|
import { WalletConnectorFactory } from '@twin.org/wallet-models';
|
|
9
|
-
import { readFile, stat } from 'node:fs/promises';
|
|
10
|
+
import { readFile, stat, readdir } from 'node:fs/promises';
|
|
10
11
|
import path from 'node:path';
|
|
12
|
+
import { CLIDisplay } from '@twin.org/cli-core';
|
|
13
|
+
import { PolicyNegotiationPointClient, DataAccessPointClient } from '@twin.org/rights-management-rest-client';
|
|
11
14
|
import { addDefaultRestPaths, addDefaultSocketPaths, EngineServer } from '@twin.org/engine-server';
|
|
12
|
-
import {
|
|
15
|
+
import { ModuleHelper } from '@twin.org/modules';
|
|
13
16
|
import * as dotenv from 'dotenv';
|
|
14
17
|
import { Engine } from '@twin.org/engine';
|
|
15
18
|
import { FileStateStorage } from '@twin.org/engine-core';
|
|
16
19
|
import { EngineCoreFactory } from '@twin.org/engine-models';
|
|
17
20
|
|
|
21
|
+
// Copyright 2024 IOTA Stiftung.
|
|
22
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
23
|
+
const ATTESTATION_VERIFICATION_METHOD_ID = "attestation-assertion";
|
|
24
|
+
const IMMUTABLE_PROOF_VERIFICATION_METHOD_ID = "immutable-proof-assertion";
|
|
25
|
+
const BLOB_STORAGE_ENCRYPTION_KEY_ID = "blob-encryption";
|
|
26
|
+
const SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID = "synchronised-storage-blob-encryption";
|
|
27
|
+
const VC_AUTHENTICATION_VERIFICATION_METHOD_ID = "node-authentication-assertion";
|
|
28
|
+
const AUTH_SIGNING_KEY_ID = "auth-signing";
|
|
29
|
+
|
|
18
30
|
// Copyright 2024 IOTA Stiftung.
|
|
19
31
|
// SPDX-License-Identifier: Apache-2.0.
|
|
20
32
|
/**
|
|
@@ -29,25 +41,28 @@ const NodeFeatures = {
|
|
|
29
41
|
/**
|
|
30
42
|
* NodeUser - generates a user for the node if not provided in config.
|
|
31
43
|
*/
|
|
32
|
-
NodeUser: "node-user"
|
|
44
|
+
NodeUser: "node-user",
|
|
45
|
+
/**
|
|
46
|
+
* NodeWallet - generates a wallet for the node and funds it when there is a faucet available.
|
|
47
|
+
*/
|
|
48
|
+
NodeWallet: "node-wallet"
|
|
33
49
|
};
|
|
34
50
|
|
|
35
51
|
// Copyright 2024 IOTA Stiftung.
|
|
36
52
|
// SPDX-License-Identifier: Apache-2.0.
|
|
37
|
-
/* eslint-disable no-console */
|
|
38
53
|
/**
|
|
39
54
|
* Initialise the locales for the application.
|
|
40
55
|
* @param localesDirectory The directory containing the locales.
|
|
41
56
|
*/
|
|
42
57
|
async function initialiseLocales(localesDirectory) {
|
|
43
58
|
const localesFile = path.resolve(path.join(localesDirectory, "en.json"));
|
|
44
|
-
|
|
59
|
+
CLIDisplay.value("Locales File", localesFile);
|
|
45
60
|
if (await fileExists(localesFile)) {
|
|
46
61
|
const enLangContent = await readFile(localesFile, "utf8");
|
|
47
62
|
I18n.addDictionary("en", JSON.parse(enLangContent));
|
|
48
63
|
}
|
|
49
64
|
else {
|
|
50
|
-
|
|
65
|
+
CLIDisplay.error(`Locales file not found: ${localesFile}`);
|
|
51
66
|
}
|
|
52
67
|
}
|
|
53
68
|
/**
|
|
@@ -71,13 +86,79 @@ async function fileExists(filename) {
|
|
|
71
86
|
return false;
|
|
72
87
|
}
|
|
73
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
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Load the text file.
|
|
149
|
+
* @param filename The filename of the text file to load.
|
|
150
|
+
* @returns The contents of the text file if it could not be loaded.
|
|
151
|
+
*/
|
|
152
|
+
async function loadTextFile(filename) {
|
|
153
|
+
return readFile(filename, "utf8");
|
|
154
|
+
}
|
|
74
155
|
/**
|
|
75
156
|
* Load the JSON file.
|
|
76
157
|
* @param filename The filename of the JSON file to load.
|
|
77
158
|
* @returns The contents of the JSON file or null if it could not be loaded.
|
|
78
159
|
*/
|
|
79
160
|
async function loadJsonFile(filename) {
|
|
80
|
-
const content = await
|
|
161
|
+
const content = await loadTextFile(filename);
|
|
81
162
|
return JSON.parse(content);
|
|
82
163
|
}
|
|
83
164
|
/**
|
|
@@ -116,8 +197,18 @@ async function bootstrap(engineCore, context, envVars) {
|
|
|
116
197
|
await bootstrapNodeUser(engineCore, context, envVars, features);
|
|
117
198
|
await bootstrapAuth(engineCore, context, envVars);
|
|
118
199
|
await bootstrapBlobEncryption(engineCore, context, envVars);
|
|
119
|
-
|
|
120
|
-
|
|
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
|
+
}
|
|
208
|
+
if (Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
|
|
209
|
+
await addVerificationMethod(engineCore, context, "verifiable credential authentication", envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID);
|
|
210
|
+
}
|
|
211
|
+
await bootstrapSynchronisedStorage(engineCore, context, envVars);
|
|
121
212
|
}
|
|
122
213
|
/**
|
|
123
214
|
* Bootstrap the node creating any necessary resources.
|
|
@@ -132,23 +223,21 @@ async function bootstrapNodeIdentity(engineCore, context, envVars, features) {
|
|
|
132
223
|
// But we have a chicken and egg problem in that we can't create the identity
|
|
133
224
|
// to store the mnemonic in the vault without an identity. We use a temporary identity
|
|
134
225
|
// and then replace it with the new identity later in the process.
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}));
|
|
151
|
-
}
|
|
226
|
+
const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
|
|
227
|
+
const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
|
|
228
|
+
const workingIdentity = envVars.identity ??
|
|
229
|
+
context.state.nodeIdentity ??
|
|
230
|
+
`bootstrap-temp-${Converter.bytesToHex(RandomHelper.generate(16))}`;
|
|
231
|
+
await bootstrapMnemonic(engineCore, envVars, features, vaultConnector, workingIdentity);
|
|
232
|
+
const addresses = await bootstrapWallet(engineCore, envVars, features, workingIdentity);
|
|
233
|
+
const finalIdentity = await bootstrapIdentity(engineCore, envVars, features, workingIdentity);
|
|
234
|
+
await finaliseWallet(engineCore, envVars, features, finalIdentity, addresses);
|
|
235
|
+
await finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity);
|
|
236
|
+
context.state.nodeIdentity = finalIdentity;
|
|
237
|
+
context.stateDirty = true;
|
|
238
|
+
engineCore.logInfo(I18n.formatMessage("node.nodeIdentity", {
|
|
239
|
+
identity: context.state.nodeIdentity
|
|
240
|
+
}));
|
|
152
241
|
}
|
|
153
242
|
}
|
|
154
243
|
/**
|
|
@@ -160,12 +249,13 @@ async function bootstrapNodeIdentity(engineCore, context, envVars, features) {
|
|
|
160
249
|
* @returns The addresses for the wallet.
|
|
161
250
|
*/
|
|
162
251
|
async function bootstrapIdentity(engineCore, envVars, features, nodeIdentity) {
|
|
163
|
-
const
|
|
252
|
+
const defaultIdentityConnectorType = engineCore.getRegisteredInstanceType("identityConnector");
|
|
164
253
|
// Now create an identity for the node controlled by the address we just funded
|
|
165
|
-
const identityConnector = IdentityConnectorFactory.get(
|
|
254
|
+
const identityConnector = IdentityConnectorFactory.get(defaultIdentityConnectorType);
|
|
166
255
|
let identityDocument;
|
|
167
256
|
try {
|
|
168
|
-
const
|
|
257
|
+
const defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType("identityResolverConnector");
|
|
258
|
+
const identityResolverConnector = IdentityResolverConnectorFactory.get(defaultIdentityResolverConnectorType);
|
|
169
259
|
identityDocument = await identityResolverConnector.resolveDocument(nodeIdentity);
|
|
170
260
|
engineCore.logInfo(I18n.formatMessage("node.existingNodeIdentity", { identity: nodeIdentity }));
|
|
171
261
|
}
|
|
@@ -175,7 +265,7 @@ async function bootstrapIdentity(engineCore, envVars, features, nodeIdentity) {
|
|
|
175
265
|
identityDocument = await identityConnector.createDocument(nodeIdentity);
|
|
176
266
|
engineCore.logInfo(I18n.formatMessage("node.createdNodeIdentity", { identity: identityDocument.id }));
|
|
177
267
|
}
|
|
178
|
-
if (
|
|
268
|
+
if (defaultIdentityConnectorType.startsWith(IdentityConnectorType.Iota)) {
|
|
179
269
|
const didUrn = Urn.fromValidString(identityDocument.id);
|
|
180
270
|
const didParts = didUrn.parts();
|
|
181
271
|
const objectId = didParts[3];
|
|
@@ -194,23 +284,26 @@ async function bootstrapIdentity(engineCore, envVars, features, nodeIdentity) {
|
|
|
194
284
|
* @returns The addresses for the wallet.
|
|
195
285
|
*/
|
|
196
286
|
async function bootstrapWallet(engineCore, envVars, features, nodeIdentity) {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
287
|
+
if (features.includes(NodeFeatures.NodeWallet)) {
|
|
288
|
+
const defaultWalletConnectorType = engineCore.getRegisteredInstanceType("walletConnector");
|
|
289
|
+
const walletConnector = WalletConnectorFactory.get(defaultWalletConnectorType);
|
|
290
|
+
const addresses = await walletConnector.getAddresses(nodeIdentity, 0, 0, 5);
|
|
291
|
+
const balance = await walletConnector.getBalance(nodeIdentity, addresses[0]);
|
|
292
|
+
if (balance === 0n) {
|
|
293
|
+
let address0 = addresses[0];
|
|
294
|
+
if (defaultWalletConnectorType.startsWith(WalletConnectorType.Iota)) {
|
|
295
|
+
address0 = `${envVars.iotaExplorerEndpoint}address/${address0}?network=${envVars.iotaNetwork}`;
|
|
296
|
+
}
|
|
297
|
+
engineCore.logInfo(I18n.formatMessage("node.fundingWallet", { address: address0 }));
|
|
298
|
+
// Add some funds to the wallet from the faucet
|
|
299
|
+
await walletConnector.ensureBalance(nodeIdentity, addresses[0], 1000000000n);
|
|
205
300
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
else {
|
|
211
|
-
engineCore.logInfo(I18n.formatMessage("node.fundedWallet"));
|
|
301
|
+
else {
|
|
302
|
+
engineCore.logInfo(I18n.formatMessage("node.fundedWallet"));
|
|
303
|
+
}
|
|
304
|
+
return addresses;
|
|
212
305
|
}
|
|
213
|
-
return
|
|
306
|
+
return [];
|
|
214
307
|
}
|
|
215
308
|
/**
|
|
216
309
|
* Bootstrap the identity for the node.
|
|
@@ -221,15 +314,17 @@ async function bootstrapWallet(engineCore, envVars, features, nodeIdentity) {
|
|
|
221
314
|
* @param addresses The addresses for the wallet.
|
|
222
315
|
*/
|
|
223
316
|
async function finaliseWallet(engineCore, envVars, features, finalIdentity, addresses) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
addr
|
|
232
|
-
|
|
317
|
+
if (features.includes(NodeFeatures.NodeWallet)) {
|
|
318
|
+
const defaultWalletConnectorType = engineCore.getRegisteredInstanceType("walletConnector");
|
|
319
|
+
// If we are using entity storage for wallet the identity associated with the
|
|
320
|
+
// address will be wrong, so fix it
|
|
321
|
+
if (defaultWalletConnectorType.startsWith(WalletConnectorType.EntityStorage)) {
|
|
322
|
+
const walletAddress = EntityStorageConnectorFactory.get("wallet-address");
|
|
323
|
+
const addr = await walletAddress.get(addresses[0]);
|
|
324
|
+
if (!Is.empty(addr)) {
|
|
325
|
+
addr.identity = finalIdentity;
|
|
326
|
+
await walletAddress.set(addr);
|
|
327
|
+
}
|
|
233
328
|
}
|
|
234
329
|
}
|
|
235
330
|
}
|
|
@@ -291,10 +386,10 @@ async function finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity)
|
|
|
291
386
|
*/
|
|
292
387
|
async function bootstrapNodeUser(engineCore, context, envVars, features) {
|
|
293
388
|
if (features.includes(NodeFeatures.NodeUser)) {
|
|
294
|
-
const
|
|
295
|
-
if (
|
|
389
|
+
const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceType("authenticationComponent");
|
|
390
|
+
if (defaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&
|
|
296
391
|
Is.stringValue(context.state.nodeIdentity)) {
|
|
297
|
-
const authUserEntityStorage = EntityStorageConnectorFactory.get(
|
|
392
|
+
const authUserEntityStorage = EntityStorageConnectorFactory.get("authentication-user");
|
|
298
393
|
const email = envVars.username ?? DEFAULT_NODE_USERNAME;
|
|
299
394
|
let nodeAdminUser = await authUserEntityStorage.get(email);
|
|
300
395
|
if (Is.empty(nodeAdminUser)) {
|
|
@@ -335,7 +430,8 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
|
|
|
335
430
|
}
|
|
336
431
|
}
|
|
337
432
|
// We have create a node user, now we need to create a profile for the user
|
|
338
|
-
const
|
|
433
|
+
const defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType("identityProfileConnector");
|
|
434
|
+
const identityProfileConnector = IdentityProfileConnectorFactory.get(defaultIdentityProfileConnectorType);
|
|
339
435
|
if (identityProfileConnector) {
|
|
340
436
|
let userProfile;
|
|
341
437
|
try {
|
|
@@ -365,43 +461,6 @@ async function bootstrapNodeUser(engineCore, context, envVars, features) {
|
|
|
365
461
|
}
|
|
366
462
|
}
|
|
367
463
|
}
|
|
368
|
-
/**
|
|
369
|
-
* Bootstrap the attestation verification methods.
|
|
370
|
-
* @param engineCore The engine core for the node.
|
|
371
|
-
* @param context The context for the node.
|
|
372
|
-
* @param envVars The environment variables for the node.
|
|
373
|
-
* @param features The features that are enabled on the node.
|
|
374
|
-
*/
|
|
375
|
-
async function bootstrapAttestationMethod(engineCore, context, envVars, features) {
|
|
376
|
-
if (Is.stringValue(context.state.nodeIdentity) &&
|
|
377
|
-
Is.arrayValue(context.config.types.identityConnector) &&
|
|
378
|
-
Is.stringValue(envVars.attestationVerificationMethodId)) {
|
|
379
|
-
const engineDefaultTypes = engineCore.getDefaultTypes();
|
|
380
|
-
const identityConnector = IdentityConnectorFactory.get(engineDefaultTypes.identityConnector);
|
|
381
|
-
const identityResolverConnector = IdentityResolverConnectorFactory.get(engineDefaultTypes.identityResolverConnector);
|
|
382
|
-
const identityDocument = await identityResolverConnector.resolveDocument(context.state.nodeIdentity);
|
|
383
|
-
const fullMethodId = `${identityDocument.id}#${envVars.attestationVerificationMethodId}`;
|
|
384
|
-
let createVm = true;
|
|
385
|
-
try {
|
|
386
|
-
DocumentHelper.getVerificationMethod(identityDocument, fullMethodId, "assertionMethod");
|
|
387
|
-
createVm = false;
|
|
388
|
-
}
|
|
389
|
-
catch { }
|
|
390
|
-
if (createVm) {
|
|
391
|
-
// Add attestation verification method to DID, the correct node context is now in place
|
|
392
|
-
// so the keys for the verification method will be stored correctly
|
|
393
|
-
engineCore.logInfo(I18n.formatMessage("node.addingAttestation", {
|
|
394
|
-
methodId: fullMethodId
|
|
395
|
-
}));
|
|
396
|
-
await identityConnector.addVerificationMethod(context.state.nodeIdentity, context.state.nodeIdentity, "assertionMethod", envVars.attestationVerificationMethodId);
|
|
397
|
-
}
|
|
398
|
-
else {
|
|
399
|
-
engineCore.logInfo(I18n.formatMessage("node.existingAttestation", {
|
|
400
|
-
methodId: fullMethodId
|
|
401
|
-
}));
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
464
|
/**
|
|
406
465
|
* Bootstrap the immutable proof verification methods.
|
|
407
466
|
* @param engineCore The engine core for the node.
|
|
@@ -409,36 +468,7 @@ async function bootstrapAttestationMethod(engineCore, context, envVars, features
|
|
|
409
468
|
* @param envVars The environment variables for the node.
|
|
410
469
|
* @param features The features that are enabled on the node.
|
|
411
470
|
*/
|
|
412
|
-
async function bootstrapImmutableProofMethod(engineCore, context, envVars, features) {
|
|
413
|
-
const engineDefaultTypes = engineCore.getDefaultTypes();
|
|
414
|
-
if (Is.stringValue(context.state.nodeIdentity) &&
|
|
415
|
-
Is.arrayValue(context.config.types.identityConnector) &&
|
|
416
|
-
Is.stringValue(envVars.immutableProofVerificationMethodId)) {
|
|
417
|
-
const identityConnector = IdentityConnectorFactory.get(engineDefaultTypes.identityConnector);
|
|
418
|
-
const identityResolverConnector = IdentityResolverConnectorFactory.get(engineDefaultTypes.identityResolverConnector);
|
|
419
|
-
const identityDocument = await identityResolverConnector.resolveDocument(context.state.nodeIdentity);
|
|
420
|
-
const fullMethodId = `${identityDocument.id}#${envVars.immutableProofVerificationMethodId}`;
|
|
421
|
-
let createVm = true;
|
|
422
|
-
try {
|
|
423
|
-
DocumentHelper.getVerificationMethod(identityDocument, fullMethodId, "assertionMethod");
|
|
424
|
-
createVm = false;
|
|
425
|
-
}
|
|
426
|
-
catch { }
|
|
427
|
-
if (createVm) {
|
|
428
|
-
// Add AIG verification method to DID, the correct node context is now in place
|
|
429
|
-
// so the keys for the verification method will be stored correctly
|
|
430
|
-
engineCore.logInfo(I18n.formatMessage("node.addingImmutableProof", {
|
|
431
|
-
methodId: fullMethodId
|
|
432
|
-
}));
|
|
433
|
-
await identityConnector.addVerificationMethod(context.state.nodeIdentity, context.state.nodeIdentity, "assertionMethod", envVars.immutableProofVerificationMethodId);
|
|
434
|
-
}
|
|
435
|
-
else {
|
|
436
|
-
engineCore.logInfo(I18n.formatMessage("node.existingImmutableProof", {
|
|
437
|
-
methodId: fullMethodId
|
|
438
|
-
}));
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
471
|
+
async function bootstrapImmutableProofMethod(engineCore, context, envVars, features) { }
|
|
442
472
|
/**
|
|
443
473
|
* Bootstrap the keys for blob encryption.
|
|
444
474
|
* @param engineCore The engine core for the node.
|
|
@@ -449,18 +479,28 @@ async function bootstrapImmutableProofMethod(engineCore, context, envVars, featu
|
|
|
449
479
|
async function bootstrapBlobEncryption(engineCore, context, envVars, features) {
|
|
450
480
|
if ((Coerce.boolean(envVars.blobStorageEnableEncryption) ?? false) &&
|
|
451
481
|
Is.stringValue(context.state.nodeIdentity)) {
|
|
452
|
-
const engineDefaultTypes = engineCore.getDefaultTypes();
|
|
453
482
|
// Create a new key for encrypting blobs
|
|
454
|
-
const
|
|
455
|
-
const
|
|
483
|
+
const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
|
|
484
|
+
const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
|
|
485
|
+
const keyName = `${context.state.nodeIdentity}/${envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID}`;
|
|
456
486
|
let existingKey;
|
|
457
487
|
try {
|
|
458
488
|
existingKey = await vaultConnector.getKey(keyName);
|
|
459
489
|
}
|
|
460
490
|
catch { }
|
|
461
491
|
if (Is.empty(existingKey)) {
|
|
462
|
-
|
|
463
|
-
|
|
492
|
+
if (Is.stringBase64(envVars.blobStorageSymmetricEncryptionKey)) {
|
|
493
|
+
engineCore.logInfo(I18n.formatMessage("node.addingBlobEncryptionKey", { keyName }));
|
|
494
|
+
await vaultConnector.addKey(keyName, VaultKeyType.ChaCha20Poly1305, Converter.base64ToBytes(envVars.blobStorageSymmetricEncryptionKey));
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
engineCore.logInfo(I18n.formatMessage("node.creatingBlobEncryptionKey", { keyName }));
|
|
498
|
+
const key = await vaultConnector.createKey(keyName, VaultKeyType.ChaCha20Poly1305);
|
|
499
|
+
engineCore.logInfo(I18n.formatMessage("node.createdBlobEncryptionKey", {
|
|
500
|
+
keyName,
|
|
501
|
+
keyValue: Converter.bytesToBase64(key)
|
|
502
|
+
}));
|
|
503
|
+
}
|
|
464
504
|
}
|
|
465
505
|
else {
|
|
466
506
|
engineCore.logInfo(I18n.formatMessage("node.existingBlobEncryptionKey", { keyName }));
|
|
@@ -475,12 +515,14 @@ async function bootstrapBlobEncryption(engineCore, context, envVars, features) {
|
|
|
475
515
|
* @param features The features that are enabled on the node.
|
|
476
516
|
*/
|
|
477
517
|
async function bootstrapAuth(engineCore, context, envVars, features) {
|
|
478
|
-
const
|
|
479
|
-
if (
|
|
518
|
+
const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceTypeOptional("authenticationComponent");
|
|
519
|
+
if (Is.stringValue(defaultAuthenticationComponentType) &&
|
|
520
|
+
defaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&
|
|
480
521
|
Is.stringValue(context.state.nodeIdentity)) {
|
|
481
522
|
// Create a new JWT signing key and a user login for the node
|
|
482
|
-
const
|
|
483
|
-
const
|
|
523
|
+
const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
|
|
524
|
+
const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
|
|
525
|
+
const keyName = `${context.state.nodeIdentity}/${envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID}`;
|
|
484
526
|
let existingKey;
|
|
485
527
|
try {
|
|
486
528
|
existingKey = await vaultConnector.getKey(keyName);
|
|
@@ -495,6 +537,74 @@ async function bootstrapAuth(engineCore, context, envVars, features) {
|
|
|
495
537
|
}
|
|
496
538
|
}
|
|
497
539
|
}
|
|
540
|
+
/**
|
|
541
|
+
* Bootstrap the synchronised storage blob encryption and verification methods.
|
|
542
|
+
* @param engineCore The engine core for the node.
|
|
543
|
+
* @param context The context for the node.
|
|
544
|
+
* @param envVars The environment variables for the node.
|
|
545
|
+
* @param features The features that are enabled on the node.
|
|
546
|
+
*/
|
|
547
|
+
async function bootstrapSynchronisedStorage(engineCore, context, envVars, features) {
|
|
548
|
+
if (Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false) {
|
|
549
|
+
// If this is a trusted node we need to add the blob encryption key pair
|
|
550
|
+
if (Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {
|
|
551
|
+
const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
|
|
552
|
+
const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
|
|
553
|
+
const keyName = envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
|
|
554
|
+
SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;
|
|
555
|
+
let existingKey;
|
|
556
|
+
try {
|
|
557
|
+
existingKey = await vaultConnector.getKey(keyName);
|
|
558
|
+
}
|
|
559
|
+
catch { }
|
|
560
|
+
if (Is.empty(existingKey)) {
|
|
561
|
+
engineCore.logInfo(I18n.formatMessage("node.addingSynchronisedStorageBlobEncryptionKey", { keyName }));
|
|
562
|
+
await vaultConnector.addKey(keyName, VaultKeyType.ChaCha20Poly1305, Converter.base64ToBytes(envVars.synchronisedStorageBlobStorageKey));
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
engineCore.logInfo(I18n.formatMessage("node.existingSynchronisedStorageBlobEncryptionKey", { keyName }));
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Add a verification method if it doesn't exist.
|
|
572
|
+
* @param engineCore The engine core for the node.
|
|
573
|
+
* @param context The context for the node.
|
|
574
|
+
* @param verificationMethodTitle The verification method title.
|
|
575
|
+
* @param verificationMethodId The verification method ID.
|
|
576
|
+
*/
|
|
577
|
+
async function addVerificationMethod(engineCore, context, verificationMethodTitle, verificationMethodId) {
|
|
578
|
+
if (Is.stringValue(context.state.nodeIdentity) &&
|
|
579
|
+
Is.arrayValue(context.config.types.identityConnector) &&
|
|
580
|
+
Is.stringValue(verificationMethodId)) {
|
|
581
|
+
const defaultIdentityConnectorType = engineCore.getRegisteredInstanceType("identityConnector");
|
|
582
|
+
const identityConnector = IdentityConnectorFactory.get(defaultIdentityConnectorType);
|
|
583
|
+
const defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType("identityResolverConnector");
|
|
584
|
+
const identityResolverConnector = IdentityResolverConnectorFactory.get(defaultIdentityResolverConnectorType);
|
|
585
|
+
const identityDocument = await identityResolverConnector.resolveDocument(context.state.nodeIdentity);
|
|
586
|
+
const fullMethodId = `${identityDocument.id}#${verificationMethodId}`;
|
|
587
|
+
let exists = false;
|
|
588
|
+
try {
|
|
589
|
+
DocumentHelper.getVerificationMethod(identityDocument, fullMethodId, "assertionMethod");
|
|
590
|
+
exists = true;
|
|
591
|
+
}
|
|
592
|
+
catch { }
|
|
593
|
+
if (!exists) {
|
|
594
|
+
engineCore.logInfo(I18n.formatMessage("node.addingVerificationMethod", {
|
|
595
|
+
title: verificationMethodTitle,
|
|
596
|
+
methodId: fullMethodId
|
|
597
|
+
}));
|
|
598
|
+
await identityConnector.addVerificationMethod(context.state.nodeIdentity, context.state.nodeIdentity, "assertionMethod", verificationMethodId);
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
engineCore.logInfo(I18n.formatMessage("node.existingVerificationMethod", {
|
|
602
|
+
title: verificationMethodTitle,
|
|
603
|
+
methodId: fullMethodId
|
|
604
|
+
}));
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
498
608
|
|
|
499
609
|
// Copyright 2024 IOTA Stiftung.
|
|
500
610
|
// SPDX-License-Identifier: Apache-2.0.
|
|
@@ -503,61 +613,51 @@ async function bootstrapAuth(engineCore, context, envVars, features) {
|
|
|
503
613
|
* @param envVars The environment variables.
|
|
504
614
|
* @returns The config for the core.
|
|
505
615
|
*/
|
|
506
|
-
function buildEngineConfiguration(envVars) {
|
|
616
|
+
async function buildEngineConfiguration(envVars) {
|
|
507
617
|
if (Is.stringValue(envVars.storageFileRoot)) {
|
|
508
618
|
envVars.stateFilename ??= "engine-state.json";
|
|
509
619
|
envVars.storageFileRoot = path.resolve(envVars.storageFileRoot);
|
|
510
620
|
envVars.stateFilename = path.join(envVars.storageFileRoot, envVars.stateFilename);
|
|
511
621
|
}
|
|
512
|
-
envVars.attestationVerificationMethodId ??= "attestation-assertion";
|
|
513
|
-
envVars.immutableProofVerificationMethodId ??= "immutable-proof-assertion";
|
|
514
|
-
envVars.blobStorageEnableEncryption ??= "false";
|
|
515
|
-
envVars.blobStorageEncryptionKey ??= "blob-encryption";
|
|
516
622
|
const coreConfig = {
|
|
517
623
|
debug: Coerce.boolean(envVars.debug) ?? false,
|
|
518
624
|
types: {}
|
|
519
625
|
};
|
|
520
|
-
configureEntityStorage(coreConfig, envVars);
|
|
521
|
-
configureBlobStorage(coreConfig, envVars);
|
|
522
|
-
configureVault(coreConfig, envVars);
|
|
523
|
-
configureDlt(coreConfig, envVars);
|
|
524
|
-
configureLogging(coreConfig, envVars);
|
|
525
|
-
configureBackgroundTask(coreConfig, envVars);
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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);
|
|
544
653
|
return coreConfig;
|
|
545
654
|
}
|
|
546
|
-
/**
|
|
547
|
-
* Helper function to get IOTA configuration from centralized dltConfig.
|
|
548
|
-
* @param coreConfig The core config.
|
|
549
|
-
* @returns The IOTA configuration if found, undefined otherwise.
|
|
550
|
-
*/
|
|
551
|
-
function getIotaConfig(coreConfig) {
|
|
552
|
-
const dltConfig = coreConfig.types.dltConfig?.find(config => config.type === DltConfigType.Iota && config.isDefault);
|
|
553
|
-
return dltConfig?.options?.config;
|
|
554
|
-
}
|
|
555
655
|
/**
|
|
556
656
|
* Configures the entity storage.
|
|
557
657
|
* @param coreConfig The core config.
|
|
558
658
|
* @param envVars The environment variables.
|
|
559
659
|
*/
|
|
560
|
-
function configureEntityStorage(coreConfig, envVars) {
|
|
660
|
+
async function configureEntityStorage(coreConfig, envVars) {
|
|
561
661
|
coreConfig.types ??= {};
|
|
562
662
|
coreConfig.types.entityStorageConnector ??= [];
|
|
563
663
|
const entityStorageConnectorTypes = envVars.entityStorageConnectorType?.split(",") ?? [];
|
|
@@ -581,9 +681,10 @@ function configureEntityStorage(coreConfig, envVars) {
|
|
|
581
681
|
options: {
|
|
582
682
|
config: {
|
|
583
683
|
region: envVars.awsDynamodbRegion ?? "",
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
684
|
+
authMode: envVars.awsDynamodbAuthMode,
|
|
685
|
+
accessKeyId: envVars.awsDynamodbAccessKeyId,
|
|
686
|
+
secretAccessKey: envVars.awsDynamodbSecretAccessKey,
|
|
687
|
+
endpoint: envVars.awsDynamodbEndpoint
|
|
587
688
|
},
|
|
588
689
|
tablePrefix: envVars.entityStorageTablePrefix
|
|
589
690
|
}
|
|
@@ -662,7 +763,7 @@ function configureEntityStorage(coreConfig, envVars) {
|
|
|
662
763
|
}
|
|
663
764
|
});
|
|
664
765
|
}
|
|
665
|
-
if (entityStorageConnectorTypes) {
|
|
766
|
+
if (entityStorageConnectorTypes.includes(EntityStorageConnectorType.PostgreSql)) {
|
|
666
767
|
coreConfig.types.entityStorageConnector.push({
|
|
667
768
|
type: EntityStorageConnectorType.PostgreSql,
|
|
668
769
|
options: {
|
|
@@ -677,10 +778,19 @@ function configureEntityStorage(coreConfig, envVars) {
|
|
|
677
778
|
}
|
|
678
779
|
});
|
|
679
780
|
}
|
|
781
|
+
const defaultEntityStorageConnectorType = envVars.entityStorageConnectorDefault ?? entityStorageConnectorTypes[0];
|
|
782
|
+
if (entityStorageConnectorTypes.includes(EntityStorageConnectorType.Synchronised)) {
|
|
783
|
+
// For synchronised storage we use the default connector as the one we wrap for real DB operations
|
|
784
|
+
coreConfig.types.entityStorageConnector.push({
|
|
785
|
+
type: EntityStorageConnectorType.Synchronised,
|
|
786
|
+
options: {
|
|
787
|
+
entityStorageConnectorType: defaultEntityStorageConnectorType
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
}
|
|
680
791
|
if (Is.arrayValue(entityStorageConnectorTypes)) {
|
|
681
|
-
const defaultStorageConnectorType = envVars.entityStorageConnectorDefault ?? entityStorageConnectorTypes[0];
|
|
682
792
|
for (const config of coreConfig.types.entityStorageConnector) {
|
|
683
|
-
if (config.type ===
|
|
793
|
+
if (config.type === defaultEntityStorageConnectorType) {
|
|
684
794
|
config.isDefault = true;
|
|
685
795
|
break;
|
|
686
796
|
}
|
|
@@ -692,7 +802,7 @@ function configureEntityStorage(coreConfig, envVars) {
|
|
|
692
802
|
* @param coreConfig The core config.
|
|
693
803
|
* @param envVars The environment variables.
|
|
694
804
|
*/
|
|
695
|
-
function configureBlobStorage(coreConfig, envVars) {
|
|
805
|
+
async function configureBlobStorage(coreConfig, envVars) {
|
|
696
806
|
coreConfig.types.blobStorageConnector ??= [];
|
|
697
807
|
const blobStorageConnectorTypes = envVars.blobStorageConnectorType?.split(",") ?? [];
|
|
698
808
|
if (blobStorageConnectorTypes.includes(BlobStorageConnectorType.Memory)) {
|
|
@@ -731,9 +841,10 @@ function configureBlobStorage(coreConfig, envVars) {
|
|
|
731
841
|
config: {
|
|
732
842
|
region: envVars.awsS3Region ?? "",
|
|
733
843
|
bucketName: envVars.awsS3BucketName ?? "",
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
844
|
+
authMode: envVars.awsS3AuthMode,
|
|
845
|
+
accessKeyId: envVars.awsS3AccessKeyId,
|
|
846
|
+
secretAccessKey: envVars.awsS3SecretAccessKey,
|
|
847
|
+
endpoint: envVars.awsS3Endpoint
|
|
737
848
|
},
|
|
738
849
|
storagePrefix: envVars.blobStoragePrefix
|
|
739
850
|
}
|
|
@@ -772,6 +883,13 @@ function configureBlobStorage(coreConfig, envVars) {
|
|
|
772
883
|
for (const config of coreConfig.types.blobStorageConnector) {
|
|
773
884
|
if (config.type === defaultStorageConnectorType) {
|
|
774
885
|
config.isDefault = true;
|
|
886
|
+
}
|
|
887
|
+
// If this blob storage connector is the one to use for public access
|
|
888
|
+
// then add it as a feature
|
|
889
|
+
if (Is.stringValue(envVars.blobStorageConnectorPublic) &&
|
|
890
|
+
config.type === envVars.blobStorageConnectorPublic) {
|
|
891
|
+
config.features ??= [];
|
|
892
|
+
config.features.push("public");
|
|
775
893
|
break;
|
|
776
894
|
}
|
|
777
895
|
}
|
|
@@ -783,7 +901,7 @@ function configureBlobStorage(coreConfig, envVars) {
|
|
|
783
901
|
options: {
|
|
784
902
|
config: {
|
|
785
903
|
vaultKeyId: (envVars.blobStorageEnableEncryption ?? false)
|
|
786
|
-
? envVars.
|
|
904
|
+
? (envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID)
|
|
787
905
|
: undefined
|
|
788
906
|
}
|
|
789
907
|
}
|
|
@@ -795,41 +913,43 @@ function configureBlobStorage(coreConfig, envVars) {
|
|
|
795
913
|
* @param coreConfig The core config.
|
|
796
914
|
* @param envVars The environment variables.
|
|
797
915
|
*/
|
|
798
|
-
function configureLogging(coreConfig, envVars) {
|
|
916
|
+
async function configureLogging(coreConfig, envVars) {
|
|
799
917
|
coreConfig.types.loggingConnector ??= [];
|
|
800
|
-
const
|
|
801
|
-
|
|
918
|
+
const loggingConnectorTypes = (envVars.loggingConnector ?? "").split(",");
|
|
919
|
+
let additionalConnectorCount = 0;
|
|
920
|
+
for (const loggingConnector of loggingConnectorTypes) {
|
|
802
921
|
if (loggingConnector === LoggingConnectorType.Console) {
|
|
803
|
-
coreConfig.types.loggingConnector
|
|
922
|
+
coreConfig.types.loggingConnector.push({
|
|
804
923
|
type: LoggingConnectorType.Console,
|
|
805
924
|
options: {
|
|
806
925
|
config: {
|
|
807
926
|
translateMessages: true,
|
|
808
927
|
hideGroups: true
|
|
809
928
|
}
|
|
810
|
-
}
|
|
811
|
-
isDefault: loggingConnectors.length === 1
|
|
929
|
+
}
|
|
812
930
|
});
|
|
931
|
+
additionalConnectorCount++;
|
|
813
932
|
}
|
|
814
933
|
else if (loggingConnector === LoggingConnectorType.EntityStorage) {
|
|
815
|
-
coreConfig.types.loggingConnector
|
|
816
|
-
type: LoggingConnectorType.EntityStorage
|
|
817
|
-
isDefault: loggingConnectors.length === 1
|
|
934
|
+
coreConfig.types.loggingConnector.push({
|
|
935
|
+
type: LoggingConnectorType.EntityStorage
|
|
818
936
|
});
|
|
937
|
+
additionalConnectorCount++;
|
|
819
938
|
}
|
|
820
939
|
}
|
|
821
|
-
if (
|
|
940
|
+
if (additionalConnectorCount > 1) {
|
|
822
941
|
coreConfig.types.loggingConnector?.push({
|
|
823
942
|
type: LoggingConnectorType.Multi,
|
|
824
|
-
isDefault: true,
|
|
825
943
|
options: {
|
|
826
|
-
loggingConnectorTypes
|
|
944
|
+
loggingConnectorTypes
|
|
827
945
|
}
|
|
828
946
|
});
|
|
829
947
|
}
|
|
830
|
-
if (
|
|
948
|
+
if (additionalConnectorCount > 0) {
|
|
831
949
|
coreConfig.types.loggingComponent ??= [];
|
|
832
|
-
|
|
950
|
+
// We set the isDefault flag so that other components will get this service by default
|
|
951
|
+
// and not the generic one from the engine core
|
|
952
|
+
coreConfig.types.loggingComponent.push({ type: LoggingComponentType.Service, isDefault: true });
|
|
833
953
|
}
|
|
834
954
|
}
|
|
835
955
|
/**
|
|
@@ -837,7 +957,7 @@ function configureLogging(coreConfig, envVars) {
|
|
|
837
957
|
* @param coreConfig The core config.
|
|
838
958
|
* @param envVars The environment variables.
|
|
839
959
|
*/
|
|
840
|
-
function configureVault(coreConfig, envVars) {
|
|
960
|
+
async function configureVault(coreConfig, envVars) {
|
|
841
961
|
coreConfig.types.vaultConnector ??= [];
|
|
842
962
|
if (envVars.vaultConnector === VaultConnectorType.EntityStorage) {
|
|
843
963
|
coreConfig.types.vaultConnector.push({
|
|
@@ -861,7 +981,7 @@ function configureVault(coreConfig, envVars) {
|
|
|
861
981
|
* @param coreConfig The core config.
|
|
862
982
|
* @param envVars The environment variables.
|
|
863
983
|
*/
|
|
864
|
-
function configureBackgroundTask(coreConfig, envVars) {
|
|
984
|
+
async function configureBackgroundTask(coreConfig, envVars) {
|
|
865
985
|
coreConfig.types.backgroundTaskConnector ??= [];
|
|
866
986
|
if (envVars.backgroundTaskConnector === BackgroundTaskConnectorType.EntityStorage) {
|
|
867
987
|
coreConfig.types.backgroundTaskConnector.push({
|
|
@@ -874,7 +994,7 @@ function configureBackgroundTask(coreConfig, envVars) {
|
|
|
874
994
|
* @param coreConfig The core config.
|
|
875
995
|
* @param envVars The environment variables.
|
|
876
996
|
*/
|
|
877
|
-
function configureEventBus(coreConfig, envVars) {
|
|
997
|
+
async function configureEventBus(coreConfig, envVars) {
|
|
878
998
|
coreConfig.types.eventBusConnector ??= [];
|
|
879
999
|
if (envVars.eventBusConnector === EventBusConnectorType.Local) {
|
|
880
1000
|
coreConfig.types.eventBusConnector.push({
|
|
@@ -891,7 +1011,7 @@ function configureEventBus(coreConfig, envVars) {
|
|
|
891
1011
|
* @param coreConfig The core config.
|
|
892
1012
|
* @param envVars The environment variables.
|
|
893
1013
|
*/
|
|
894
|
-
function configureTelemetry(coreConfig, envVars) {
|
|
1014
|
+
async function configureTelemetry(coreConfig, envVars) {
|
|
895
1015
|
coreConfig.types.telemetryConnector ??= [];
|
|
896
1016
|
if (envVars.telemetryConnector === TelemetryConnectorType.EntityStorage) {
|
|
897
1017
|
coreConfig.types.telemetryConnector.push({
|
|
@@ -908,71 +1028,84 @@ function configureTelemetry(coreConfig, envVars) {
|
|
|
908
1028
|
* @param coreConfig The core config.
|
|
909
1029
|
* @param envVars The environment variables.
|
|
910
1030
|
*/
|
|
911
|
-
function configureMessaging(coreConfig, envVars) {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1031
|
+
async function configureMessaging(coreConfig, envVars) {
|
|
1032
|
+
if (Coerce.boolean(envVars.messagingEnabled) ?? false) {
|
|
1033
|
+
coreConfig.types.messagingEmailConnector ??= [];
|
|
1034
|
+
coreConfig.types.messagingSmsConnector ??= [];
|
|
1035
|
+
coreConfig.types.messagingPushNotificationConnector ??= [];
|
|
1036
|
+
if (envVars.messagingEmailConnector === MessagingEmailConnectorType.EntityStorage) {
|
|
1037
|
+
coreConfig.types.messagingEmailConnector.push({
|
|
1038
|
+
type: MessagingEmailConnectorType.EntityStorage
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
else if (envVars.messagingEmailConnector === MessagingEmailConnectorType.Aws) {
|
|
1042
|
+
coreConfig.types.messagingEmailConnector.push({
|
|
1043
|
+
type: MessagingEmailConnectorType.Aws,
|
|
1044
|
+
options: {
|
|
1045
|
+
config: {
|
|
1046
|
+
region: envVars.awsSesRegion ?? "",
|
|
1047
|
+
authMode: envVars.awsSesAuthMode,
|
|
1048
|
+
accessKeyId: envVars.awsSesAccessKeyId,
|
|
1049
|
+
secretAccessKey: envVars.awsSesSecretAccessKey,
|
|
1050
|
+
endpoint: envVars.awsSesEndpoint
|
|
1051
|
+
}
|
|
929
1052
|
}
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
if (envVars.messagingSmsConnector === MessagingSmsConnectorType.EntityStorage) {
|
|
1056
|
+
coreConfig.types.messagingSmsConnector.push({
|
|
1057
|
+
type: MessagingSmsConnectorType.EntityStorage
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
else if (envVars.messagingSmsConnector === MessagingSmsConnectorType.Aws) {
|
|
1061
|
+
coreConfig.types.messagingSmsConnector.push({
|
|
1062
|
+
type: MessagingSmsConnectorType.Aws,
|
|
1063
|
+
options: {
|
|
1064
|
+
config: {
|
|
1065
|
+
region: envVars.awsSesRegion ?? "",
|
|
1066
|
+
authMode: envVars.awsSesAuthMode,
|
|
1067
|
+
accessKeyId: envVars.awsSesAccessKeyId,
|
|
1068
|
+
secretAccessKey: envVars.awsSesSecretAccessKey,
|
|
1069
|
+
endpoint: envVars.awsSesEndpoint
|
|
1070
|
+
}
|
|
947
1071
|
}
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
if (envVars.messagingPushNotificationConnector ===
|
|
1075
|
+
MessagingPushNotificationConnectorType.EntityStorage) {
|
|
1076
|
+
coreConfig.types.messagingPushNotificationConnector.push({
|
|
1077
|
+
type: MessagingPushNotificationConnectorType.EntityStorage
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
else if (envVars.messagingPushNotificationConnector === MessagingPushNotificationConnectorType.Aws) {
|
|
1081
|
+
coreConfig.types.messagingPushNotificationConnector.push({
|
|
1082
|
+
type: MessagingPushNotificationConnectorType.Aws,
|
|
1083
|
+
options: {
|
|
1084
|
+
config: {
|
|
1085
|
+
region: envVars.awsSesRegion ?? "",
|
|
1086
|
+
authMode: envVars.awsSesAuthMode,
|
|
1087
|
+
accessKeyId: envVars.awsSesAccessKeyId,
|
|
1088
|
+
secretAccessKey: envVars.awsSesSecretAccessKey,
|
|
1089
|
+
endpoint: envVars.awsSesEndpoint,
|
|
1090
|
+
applicationsSettings: Is.json(envVars.awsMessagingPushNotificationApplications)
|
|
1091
|
+
? JSON.parse(envVars.awsMessagingPushNotificationApplications)
|
|
1092
|
+
: []
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
const templates = Is.arrayValue(envVars.messagingTemplates)
|
|
1098
|
+
? envVars.messagingTemplates
|
|
1099
|
+
: undefined;
|
|
1100
|
+
coreConfig.types.messagingAdminComponent ??= [];
|
|
1101
|
+
coreConfig.types.messagingAdminComponent.push({
|
|
1102
|
+
type: MessagingAdminComponentType.Service,
|
|
960
1103
|
options: {
|
|
961
1104
|
config: {
|
|
962
|
-
|
|
963
|
-
accessKeyId: envVars.awsS3AccessKeyId ?? "",
|
|
964
|
-
secretAccessKey: envVars.awsS3SecretAccessKey ?? "",
|
|
965
|
-
endpoint: envVars.awsS3Endpoint ?? "",
|
|
966
|
-
applicationsSettings: Is.json(envVars.awsMessagingPushNotificationApplications)
|
|
967
|
-
? JSON.parse(envVars.awsMessagingPushNotificationApplications)
|
|
968
|
-
: []
|
|
1105
|
+
templates
|
|
969
1106
|
}
|
|
970
1107
|
}
|
|
971
1108
|
});
|
|
972
|
-
}
|
|
973
|
-
if (coreConfig.types.messagingEmailConnector.length > 0 ||
|
|
974
|
-
coreConfig.types.messagingSmsConnector.length > 0 ||
|
|
975
|
-
coreConfig.types.messagingPushNotificationConnector.length > 0) {
|
|
976
1109
|
coreConfig.types.messagingComponent ??= [];
|
|
977
1110
|
coreConfig.types.messagingComponent.push({ type: MessagingComponentType.Service });
|
|
978
1111
|
}
|
|
@@ -982,7 +1115,7 @@ function configureMessaging(coreConfig, envVars) {
|
|
|
982
1115
|
* @param coreConfig The core config.
|
|
983
1116
|
* @param envVars The environment variables.
|
|
984
1117
|
*/
|
|
985
|
-
function configureFaucet(coreConfig, envVars) {
|
|
1118
|
+
async function configureFaucet(coreConfig, envVars) {
|
|
986
1119
|
coreConfig.types.faucetConnector ??= [];
|
|
987
1120
|
if (envVars.faucetConnector === FaucetConnectorType.EntityStorage) {
|
|
988
1121
|
coreConfig.types.faucetConnector.push({
|
|
@@ -990,14 +1123,14 @@ function configureFaucet(coreConfig, envVars) {
|
|
|
990
1123
|
});
|
|
991
1124
|
}
|
|
992
1125
|
else if (envVars.faucetConnector === FaucetConnectorType.Iota) {
|
|
993
|
-
const
|
|
1126
|
+
const dltConfig = EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", DltConfigType.Iota);
|
|
994
1127
|
coreConfig.types.faucetConnector.push({
|
|
995
1128
|
type: FaucetConnectorType.Iota,
|
|
996
1129
|
options: {
|
|
997
1130
|
config: {
|
|
998
1131
|
endpoint: envVars.iotaFaucetEndpoint ?? "",
|
|
999
|
-
clientOptions:
|
|
1000
|
-
network:
|
|
1132
|
+
clientOptions: dltConfig?.options?.config?.clientOptions ?? { url: "" },
|
|
1133
|
+
network: dltConfig?.options?.config?.network ?? ""
|
|
1001
1134
|
}
|
|
1002
1135
|
}
|
|
1003
1136
|
});
|
|
@@ -1008,7 +1141,7 @@ function configureFaucet(coreConfig, envVars) {
|
|
|
1008
1141
|
* @param coreConfig The core config.
|
|
1009
1142
|
* @param envVars The environment variables.
|
|
1010
1143
|
*/
|
|
1011
|
-
function configureWallet(coreConfig, envVars) {
|
|
1144
|
+
async function configureWallet(coreConfig, envVars) {
|
|
1012
1145
|
coreConfig.types.walletConnector ??= [];
|
|
1013
1146
|
if (envVars.walletConnector === WalletConnectorType.EntityStorage) {
|
|
1014
1147
|
coreConfig.types.walletConnector.push({
|
|
@@ -1016,11 +1149,11 @@ function configureWallet(coreConfig, envVars) {
|
|
|
1016
1149
|
});
|
|
1017
1150
|
}
|
|
1018
1151
|
else if (envVars.walletConnector === WalletConnectorType.Iota) {
|
|
1019
|
-
const
|
|
1152
|
+
const dltConfig = EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", DltConfigType.Iota);
|
|
1020
1153
|
coreConfig.types.walletConnector.push({
|
|
1021
1154
|
type: WalletConnectorType.Iota,
|
|
1022
1155
|
options: {
|
|
1023
|
-
config:
|
|
1156
|
+
config: dltConfig?.options?.config ?? {}
|
|
1024
1157
|
}
|
|
1025
1158
|
});
|
|
1026
1159
|
}
|
|
@@ -1030,7 +1163,7 @@ function configureWallet(coreConfig, envVars) {
|
|
|
1030
1163
|
* @param coreConfig The core config.
|
|
1031
1164
|
* @param envVars The environment variables.
|
|
1032
1165
|
*/
|
|
1033
|
-
function configureNft(coreConfig, envVars) {
|
|
1166
|
+
async function configureNft(coreConfig, envVars) {
|
|
1034
1167
|
coreConfig.types.nftConnector ??= [];
|
|
1035
1168
|
if (envVars.nftConnector === NftConnectorType.EntityStorage) {
|
|
1036
1169
|
coreConfig.types.nftConnector.push({
|
|
@@ -1038,11 +1171,11 @@ function configureNft(coreConfig, envVars) {
|
|
|
1038
1171
|
});
|
|
1039
1172
|
}
|
|
1040
1173
|
else if (envVars.nftConnector === NftConnectorType.Iota) {
|
|
1041
|
-
const
|
|
1174
|
+
const dltConfig = EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", DltConfigType.Iota);
|
|
1042
1175
|
coreConfig.types.nftConnector.push({
|
|
1043
1176
|
type: NftConnectorType.Iota,
|
|
1044
1177
|
options: {
|
|
1045
|
-
config:
|
|
1178
|
+
config: dltConfig?.options?.config ?? {}
|
|
1046
1179
|
}
|
|
1047
1180
|
});
|
|
1048
1181
|
}
|
|
@@ -1056,7 +1189,7 @@ function configureNft(coreConfig, envVars) {
|
|
|
1056
1189
|
* @param coreConfig The core config.
|
|
1057
1190
|
* @param envVars The environment variables.
|
|
1058
1191
|
*/
|
|
1059
|
-
function configureVerifiableStorage(coreConfig, envVars) {
|
|
1192
|
+
async function configureVerifiableStorage(coreConfig, envVars) {
|
|
1060
1193
|
coreConfig.types.verifiableStorageConnector ??= [];
|
|
1061
1194
|
if (envVars.verifiableStorageConnector === VerifiableStorageConnectorType.EntityStorage) {
|
|
1062
1195
|
coreConfig.types.verifiableStorageConnector.push({
|
|
@@ -1064,11 +1197,11 @@ function configureVerifiableStorage(coreConfig, envVars) {
|
|
|
1064
1197
|
});
|
|
1065
1198
|
}
|
|
1066
1199
|
else if (envVars.verifiableStorageConnector === VerifiableStorageConnectorType.Iota) {
|
|
1067
|
-
const
|
|
1200
|
+
const dltConfig = EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", DltConfigType.Iota);
|
|
1068
1201
|
coreConfig.types.verifiableStorageConnector.push({
|
|
1069
1202
|
type: VerifiableStorageConnectorType.Iota,
|
|
1070
1203
|
options: {
|
|
1071
|
-
config:
|
|
1204
|
+
config: dltConfig?.options?.config ?? {}
|
|
1072
1205
|
}
|
|
1073
1206
|
});
|
|
1074
1207
|
}
|
|
@@ -1082,18 +1215,10 @@ function configureVerifiableStorage(coreConfig, envVars) {
|
|
|
1082
1215
|
type: ImmutableProofComponentType.Service,
|
|
1083
1216
|
options: {
|
|
1084
1217
|
config: {
|
|
1085
|
-
verificationMethodId: envVars.immutableProofVerificationMethodId
|
|
1218
|
+
verificationMethodId: envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID
|
|
1086
1219
|
}
|
|
1087
1220
|
}
|
|
1088
1221
|
});
|
|
1089
|
-
coreConfig.types.auditableItemGraphComponent ??= [];
|
|
1090
|
-
coreConfig.types.auditableItemGraphComponent.push({
|
|
1091
|
-
type: AuditableItemGraphComponentType.Service
|
|
1092
|
-
});
|
|
1093
|
-
coreConfig.types.auditableItemStreamComponent ??= [];
|
|
1094
|
-
coreConfig.types.auditableItemStreamComponent.push({
|
|
1095
|
-
type: AuditableItemStreamComponentType.Service
|
|
1096
|
-
});
|
|
1097
1222
|
}
|
|
1098
1223
|
}
|
|
1099
1224
|
/**
|
|
@@ -1101,7 +1226,7 @@ function configureVerifiableStorage(coreConfig, envVars) {
|
|
|
1101
1226
|
* @param coreConfig The core config.
|
|
1102
1227
|
* @param envVars The environment variables.
|
|
1103
1228
|
*/
|
|
1104
|
-
function configureIdentity(coreConfig, envVars) {
|
|
1229
|
+
async function configureIdentity(coreConfig, envVars) {
|
|
1105
1230
|
coreConfig.types.identityConnector ??= [];
|
|
1106
1231
|
if (envVars.identityConnector === IdentityConnectorType.EntityStorage) {
|
|
1107
1232
|
coreConfig.types.identityConnector.push({
|
|
@@ -1109,11 +1234,11 @@ function configureIdentity(coreConfig, envVars) {
|
|
|
1109
1234
|
});
|
|
1110
1235
|
}
|
|
1111
1236
|
else if (envVars.identityConnector === IdentityConnectorType.Iota) {
|
|
1112
|
-
const
|
|
1237
|
+
const dltConfig = EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", DltConfigType.Iota);
|
|
1113
1238
|
coreConfig.types.identityConnector.push({
|
|
1114
1239
|
type: IdentityConnectorType.Iota,
|
|
1115
1240
|
options: {
|
|
1116
|
-
config:
|
|
1241
|
+
config: dltConfig?.options?.config ?? {}
|
|
1117
1242
|
}
|
|
1118
1243
|
});
|
|
1119
1244
|
}
|
|
@@ -1127,7 +1252,7 @@ function configureIdentity(coreConfig, envVars) {
|
|
|
1127
1252
|
* @param coreConfig The core config.
|
|
1128
1253
|
* @param envVars The environment variables.
|
|
1129
1254
|
*/
|
|
1130
|
-
function configureIdentityResolver(coreConfig, envVars) {
|
|
1255
|
+
async function configureIdentityResolver(coreConfig, envVars) {
|
|
1131
1256
|
coreConfig.types.identityResolverConnector ??= [];
|
|
1132
1257
|
if (envVars.identityResolverConnector === IdentityResolverConnectorType.EntityStorage) {
|
|
1133
1258
|
coreConfig.types.identityResolverConnector.push({
|
|
@@ -1135,11 +1260,11 @@ function configureIdentityResolver(coreConfig, envVars) {
|
|
|
1135
1260
|
});
|
|
1136
1261
|
}
|
|
1137
1262
|
else if (envVars.identityResolverConnector === IdentityResolverConnectorType.Iota) {
|
|
1138
|
-
const
|
|
1263
|
+
const dltConfig = EngineTypeHelper.getConfigOfType(coreConfig, "dltConfig", DltConfigType.Iota);
|
|
1139
1264
|
coreConfig.types.identityResolverConnector.push({
|
|
1140
1265
|
type: IdentityResolverConnectorType.Iota,
|
|
1141
1266
|
options: {
|
|
1142
|
-
config:
|
|
1267
|
+
config: dltConfig?.options?.config ?? {}
|
|
1143
1268
|
}
|
|
1144
1269
|
});
|
|
1145
1270
|
}
|
|
@@ -1165,7 +1290,7 @@ function configureIdentityResolver(coreConfig, envVars) {
|
|
|
1165
1290
|
* @param coreConfig The core config.
|
|
1166
1291
|
* @param envVars The environment variables.
|
|
1167
1292
|
*/
|
|
1168
|
-
function configureIdentityProfile(coreConfig, envVars) {
|
|
1293
|
+
async function configureIdentityProfile(coreConfig, envVars) {
|
|
1169
1294
|
coreConfig.types.identityProfileConnector ??= [];
|
|
1170
1295
|
if (envVars.identityProfileConnector === IdentityConnectorType.EntityStorage) {
|
|
1171
1296
|
coreConfig.types.identityProfileConnector.push({
|
|
@@ -1182,7 +1307,7 @@ function configureIdentityProfile(coreConfig, envVars) {
|
|
|
1182
1307
|
* @param coreConfig The core config.
|
|
1183
1308
|
* @param envVars The environment variables.
|
|
1184
1309
|
*/
|
|
1185
|
-
function configureAttestation(coreConfig, envVars) {
|
|
1310
|
+
async function configureAttestation(coreConfig, envVars) {
|
|
1186
1311
|
coreConfig.types.attestationConnector ??= [];
|
|
1187
1312
|
if (envVars.attestationConnector === AttestationConnectorType.Nft) {
|
|
1188
1313
|
coreConfig.types.attestationConnector.push({
|
|
@@ -1195,7 +1320,7 @@ function configureAttestation(coreConfig, envVars) {
|
|
|
1195
1320
|
type: AttestationComponentType.Service,
|
|
1196
1321
|
options: {
|
|
1197
1322
|
config: {
|
|
1198
|
-
verificationMethodId: envVars.attestationVerificationMethodId
|
|
1323
|
+
verificationMethodId: envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID
|
|
1199
1324
|
}
|
|
1200
1325
|
}
|
|
1201
1326
|
});
|
|
@@ -1206,8 +1331,8 @@ function configureAttestation(coreConfig, envVars) {
|
|
|
1206
1331
|
* @param coreConfig The core config.
|
|
1207
1332
|
* @param envVars The environment variables.
|
|
1208
1333
|
*/
|
|
1209
|
-
function configureAuditableItemGraph(coreConfig, envVars) {
|
|
1210
|
-
if (
|
|
1334
|
+
async function configureAuditableItemGraph(coreConfig, envVars) {
|
|
1335
|
+
if (Coerce.boolean(envVars.auditableItemGraphEnabled) ?? false) {
|
|
1211
1336
|
coreConfig.types.auditableItemGraphComponent ??= [];
|
|
1212
1337
|
coreConfig.types.auditableItemGraphComponent.push({
|
|
1213
1338
|
type: AuditableItemGraphComponentType.Service
|
|
@@ -1219,8 +1344,8 @@ function configureAuditableItemGraph(coreConfig, envVars) {
|
|
|
1219
1344
|
* @param coreConfig The core config.
|
|
1220
1345
|
* @param envVars The environment variables.
|
|
1221
1346
|
*/
|
|
1222
|
-
function configureAuditableItemStream(coreConfig, envVars) {
|
|
1223
|
-
if (
|
|
1347
|
+
async function configureAuditableItemStream(coreConfig, envVars) {
|
|
1348
|
+
if (Coerce.boolean(envVars.auditableItemStreamEnabled) ?? false) {
|
|
1224
1349
|
coreConfig.types.auditableItemStreamComponent ??= [];
|
|
1225
1350
|
coreConfig.types.auditableItemStreamComponent.push({
|
|
1226
1351
|
type: AuditableItemStreamComponentType.Service
|
|
@@ -1232,34 +1357,33 @@ function configureAuditableItemStream(coreConfig, envVars) {
|
|
|
1232
1357
|
* @param coreConfig The core config.
|
|
1233
1358
|
* @param envVars The environment variables.
|
|
1234
1359
|
*/
|
|
1235
|
-
function configureDataProcessing(coreConfig, envVars) {
|
|
1236
|
-
|
|
1237
|
-
coreConfig.types.dataExtractorConnector ??= [];
|
|
1238
|
-
const converterConnectors = envVars.dataConverterConnectors?.split(",") ?? [];
|
|
1239
|
-
for (const converterConnector of converterConnectors) {
|
|
1240
|
-
if (converterConnector === DataConverterConnectorType.Json) {
|
|
1241
|
-
coreConfig.types.dataConverterConnector.push({
|
|
1242
|
-
type: DataConverterConnectorType.Json
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1245
|
-
else if (converterConnector === DataConverterConnectorType.Xml) {
|
|
1246
|
-
coreConfig.types.dataConverterConnector.push({
|
|
1247
|
-
type: DataConverterConnectorType.Xml
|
|
1248
|
-
});
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1251
|
-
const extractorConnectors = envVars.dataExtractorConnectors?.split(",") ?? [];
|
|
1252
|
-
for (const extractorConnector of extractorConnectors) {
|
|
1253
|
-
if (extractorConnector === DataExtractorConnectorType.JsonPath) {
|
|
1254
|
-
coreConfig.types.dataExtractorConnector.push({
|
|
1255
|
-
type: DataExtractorConnectorType.JsonPath
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
if (coreConfig.types.dataConverterConnector.length > 0 ||
|
|
1260
|
-
coreConfig.types.dataExtractorConnector.length > 0) {
|
|
1360
|
+
async function configureDataProcessing(coreConfig, envVars) {
|
|
1361
|
+
if (Coerce.boolean(envVars.dataProcessingEnabled) ?? false) {
|
|
1261
1362
|
coreConfig.types.dataProcessingComponent ??= [];
|
|
1262
1363
|
coreConfig.types.dataProcessingComponent.push({ type: DataProcessingComponentType.Service });
|
|
1364
|
+
coreConfig.types.dataConverterConnector ??= [];
|
|
1365
|
+
const converterConnectors = envVars.dataConverterConnectors?.split(",") ?? [];
|
|
1366
|
+
for (const converterConnector of converterConnectors) {
|
|
1367
|
+
if (converterConnector === DataConverterConnectorType.Json) {
|
|
1368
|
+
coreConfig.types.dataConverterConnector.push({
|
|
1369
|
+
type: DataConverterConnectorType.Json
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
else if (converterConnector === DataConverterConnectorType.Xml) {
|
|
1373
|
+
coreConfig.types.dataConverterConnector.push({
|
|
1374
|
+
type: DataConverterConnectorType.Xml
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
coreConfig.types.dataExtractorConnector ??= [];
|
|
1379
|
+
const extractorConnectors = envVars.dataExtractorConnectors?.split(",") ?? [];
|
|
1380
|
+
for (const extractorConnector of extractorConnectors) {
|
|
1381
|
+
if (extractorConnector === DataExtractorConnectorType.JsonPath) {
|
|
1382
|
+
coreConfig.types.dataExtractorConnector.push({
|
|
1383
|
+
type: DataExtractorConnectorType.JsonPath
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1263
1387
|
}
|
|
1264
1388
|
}
|
|
1265
1389
|
/**
|
|
@@ -1267,10 +1391,8 @@ function configureDataProcessing(coreConfig, envVars) {
|
|
|
1267
1391
|
* @param coreConfig The core config.
|
|
1268
1392
|
* @param envVars The environment variables.
|
|
1269
1393
|
*/
|
|
1270
|
-
function configureDocumentManagement(coreConfig, envVars) {
|
|
1271
|
-
if (
|
|
1272
|
-
Is.arrayValue(coreConfig.types.blobStorageComponent) &&
|
|
1273
|
-
Is.arrayValue(coreConfig.types.attestationComponent)) {
|
|
1394
|
+
async function configureDocumentManagement(coreConfig, envVars) {
|
|
1395
|
+
if (Coerce.boolean(envVars.documentManagementEnabled) ?? false) {
|
|
1274
1396
|
coreConfig.types.documentManagementComponent ??= [];
|
|
1275
1397
|
coreConfig.types.documentManagementComponent.push({
|
|
1276
1398
|
type: DocumentManagementComponentType.Service
|
|
@@ -1278,21 +1400,22 @@ function configureDocumentManagement(coreConfig, envVars) {
|
|
|
1278
1400
|
}
|
|
1279
1401
|
}
|
|
1280
1402
|
/**
|
|
1281
|
-
* Configures the
|
|
1403
|
+
* Configures the verifiable credential authentication.
|
|
1282
1404
|
* @param coreConfig The core config.
|
|
1283
1405
|
* @param envVars The environment variables.
|
|
1284
1406
|
*/
|
|
1285
|
-
function
|
|
1286
|
-
if (
|
|
1287
|
-
|
|
1288
|
-
coreConfig.types.
|
|
1289
|
-
|
|
1407
|
+
async function configureVerifiableCredentialAuthentication(coreConfig, envVars) {
|
|
1408
|
+
if (Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
|
|
1409
|
+
// Can only perform VC authentication if identity component is available
|
|
1410
|
+
coreConfig.types.authenticationGeneratorComponent ??= [];
|
|
1411
|
+
coreConfig.types.authenticationGeneratorComponent.push({
|
|
1412
|
+
type: AuthenticationGeneratorComponentType.VerifiableCredential,
|
|
1290
1413
|
options: {
|
|
1291
1414
|
config: {
|
|
1292
|
-
|
|
1293
|
-
clearingHouseApproverList: Coerce.object(envVars.federatedCatalogueClearingHouseApproverList) ?? []
|
|
1415
|
+
verificationMethodId: envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID
|
|
1294
1416
|
}
|
|
1295
|
-
}
|
|
1417
|
+
},
|
|
1418
|
+
features: ["verifiable-credential"]
|
|
1296
1419
|
});
|
|
1297
1420
|
}
|
|
1298
1421
|
}
|
|
@@ -1301,15 +1424,87 @@ function configureFederatedCatalogue(coreConfig, envVars) {
|
|
|
1301
1424
|
* @param coreConfig The core config.
|
|
1302
1425
|
* @param envVars The environment variables.
|
|
1303
1426
|
*/
|
|
1304
|
-
function configureRightsManagement(coreConfig, envVars) {
|
|
1427
|
+
async function configureRightsManagement(coreConfig, envVars) {
|
|
1305
1428
|
if (Coerce.boolean(envVars.rightsManagementEnabled) ?? false) {
|
|
1306
1429
|
coreConfig.types.rightsManagementPapComponent ??= [];
|
|
1307
1430
|
coreConfig.types.rightsManagementPapComponent.push({
|
|
1308
1431
|
type: RightsManagementPapComponentType.Service
|
|
1309
1432
|
});
|
|
1310
|
-
coreConfig.types.
|
|
1311
|
-
coreConfig.types.
|
|
1312
|
-
type:
|
|
1433
|
+
coreConfig.types.rightsManagementPmpComponent ??= [];
|
|
1434
|
+
coreConfig.types.rightsManagementPmpComponent.push({
|
|
1435
|
+
type: RightsManagementPmpComponentType.Service
|
|
1436
|
+
});
|
|
1437
|
+
coreConfig.types.rightsManagementPipComponent ??= [];
|
|
1438
|
+
coreConfig.types.rightsManagementPipComponent.push({
|
|
1439
|
+
type: RightsManagementPipComponentType.Service,
|
|
1440
|
+
options: {
|
|
1441
|
+
informationModulesConfig: Is.arrayValue(envVars.rightsManagementInformationSources)
|
|
1442
|
+
? envVars.rightsManagementInformationSources
|
|
1443
|
+
: undefined
|
|
1444
|
+
}
|
|
1445
|
+
});
|
|
1446
|
+
coreConfig.types.rightsManagementPxpComponent ??= [];
|
|
1447
|
+
coreConfig.types.rightsManagementPxpComponent.push({
|
|
1448
|
+
type: RightsManagementPxpComponentType.Service,
|
|
1449
|
+
options: {
|
|
1450
|
+
actionModulesConfig: Is.arrayValue(envVars.rightsManagementExecutionActions)
|
|
1451
|
+
? envVars.rightsManagementExecutionActions
|
|
1452
|
+
: undefined
|
|
1453
|
+
}
|
|
1454
|
+
});
|
|
1455
|
+
coreConfig.types.rightsManagementPdpComponent ??= [];
|
|
1456
|
+
coreConfig.types.rightsManagementPdpComponent.push({
|
|
1457
|
+
type: RightsManagementPdpComponentType.Service,
|
|
1458
|
+
options: {
|
|
1459
|
+
arbiterModulesConfig: Is.arrayValue(envVars.rightsManagementArbiters)
|
|
1460
|
+
? envVars.rightsManagementArbiters
|
|
1461
|
+
: undefined
|
|
1462
|
+
}
|
|
1463
|
+
});
|
|
1464
|
+
coreConfig.types.rightsManagementPepComponent ??= [];
|
|
1465
|
+
coreConfig.types.rightsManagementPepComponent.push({
|
|
1466
|
+
type: RightsManagementPepComponentType.Service,
|
|
1467
|
+
options: {
|
|
1468
|
+
processorModulesConfig: Is.arrayValue(envVars.rightsManagementEnforcementProcessors)
|
|
1469
|
+
? envVars.rightsManagementEnforcementProcessors
|
|
1470
|
+
: undefined
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
coreConfig.types.rightsManagementPnpComponent ??= [];
|
|
1474
|
+
coreConfig.types.rightsManagementPnpComponent.push({
|
|
1475
|
+
type: RightsManagementPnpComponentType.Service,
|
|
1476
|
+
options: {
|
|
1477
|
+
negotiatorModulesConfig: Is.arrayValue(envVars.rightsManagementNegotiators)
|
|
1478
|
+
? envVars.rightsManagementNegotiators
|
|
1479
|
+
: undefined,
|
|
1480
|
+
requesterModulesConfig: Is.arrayValue(envVars.rightsManagementRequesters)
|
|
1481
|
+
? envVars.rightsManagementRequesters
|
|
1482
|
+
: undefined,
|
|
1483
|
+
config: {
|
|
1484
|
+
baseCallbackUrl: envVars.rightsManagementBaseCallbackUrl ?? "",
|
|
1485
|
+
offers: Is.arrayValue(envVars.rightsManagementOffers)
|
|
1486
|
+
? envVars.rightsManagementOffers
|
|
1487
|
+
: [],
|
|
1488
|
+
negotiationComponentCreator: async (url) => new PolicyNegotiationPointClient({ endpoint: url })
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
});
|
|
1492
|
+
coreConfig.types.rightsManagementPnapComponent ??= [];
|
|
1493
|
+
coreConfig.types.rightsManagementPnapComponent.push({
|
|
1494
|
+
type: RightsManagementPnapComponentType.Service
|
|
1495
|
+
});
|
|
1496
|
+
coreConfig.types.rightsManagementDapComponent ??= [];
|
|
1497
|
+
coreConfig.types.rightsManagementDapComponent.push({
|
|
1498
|
+
type: RightsManagementDapComponentType.Service
|
|
1499
|
+
});
|
|
1500
|
+
coreConfig.types.rightsManagementDarpComponent ??= [];
|
|
1501
|
+
coreConfig.types.rightsManagementDarpComponent.push({
|
|
1502
|
+
type: RightsManagementDarpComponentType.Service,
|
|
1503
|
+
options: {
|
|
1504
|
+
config: {
|
|
1505
|
+
dataAccessComponentCreator: async (url) => new DataAccessPointClient({ endpoint: url })
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1313
1508
|
});
|
|
1314
1509
|
}
|
|
1315
1510
|
}
|
|
@@ -1318,11 +1513,92 @@ function configureRightsManagement(coreConfig, envVars) {
|
|
|
1318
1513
|
* @param coreConfig The core config.
|
|
1319
1514
|
* @param envVars The environment variables.
|
|
1320
1515
|
*/
|
|
1321
|
-
function configureTaskScheduler(coreConfig, envVars) {
|
|
1322
|
-
if (Coerce.boolean(envVars.taskSchedulerEnabled) ??
|
|
1516
|
+
async function configureTaskScheduler(coreConfig, envVars) {
|
|
1517
|
+
if (Coerce.boolean(envVars.taskSchedulerEnabled) ?? false) {
|
|
1323
1518
|
coreConfig.types.taskSchedulerComponent ??= [];
|
|
1324
1519
|
coreConfig.types.taskSchedulerComponent.push({
|
|
1325
|
-
type: TaskSchedulerComponentType.
|
|
1520
|
+
type: TaskSchedulerComponentType.Service
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Configures the synchronised storage.
|
|
1526
|
+
* @param coreConfig The core config.
|
|
1527
|
+
* @param envVars The environment variables.
|
|
1528
|
+
*/
|
|
1529
|
+
async function configureSynchronisedStorage(coreConfig, envVars) {
|
|
1530
|
+
if (Is.arrayValue(coreConfig.types.identityResolverComponent) &&
|
|
1531
|
+
(Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false)) {
|
|
1532
|
+
// Check if the config provides a custom verifiable storage key id
|
|
1533
|
+
let verifiableStorageKeyId = Coerce.string(envVars.synchronisedStorageVerifiableStorageKeyId);
|
|
1534
|
+
if (!Is.stringValue(verifiableStorageKeyId)) {
|
|
1535
|
+
// No custom key so default to the network setting
|
|
1536
|
+
verifiableStorageKeyId = envVars.iotaNetwork;
|
|
1537
|
+
}
|
|
1538
|
+
coreConfig.types.synchronisedStorageComponent ??= [];
|
|
1539
|
+
coreConfig.types.synchronisedStorageComponent.push({
|
|
1540
|
+
type: SynchronisedStorageComponentType.Service,
|
|
1541
|
+
options: {
|
|
1542
|
+
config: {
|
|
1543
|
+
verifiableStorageKeyId: verifiableStorageKeyId ?? "",
|
|
1544
|
+
blobStorageEncryptionKeyId: envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
|
|
1545
|
+
SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID,
|
|
1546
|
+
entityUpdateIntervalMinutes: Coerce.number(envVars.synchronisedStorageEntityUpdateIntervalMinutes),
|
|
1547
|
+
consolidationIntervalMinutes: Coerce.number(envVars.synchronisedStorageConsolidationIntervalMinutes),
|
|
1548
|
+
consolidationBatchSize: Coerce.number(envVars.synchronisedStorageConsolidationBatchSize),
|
|
1549
|
+
maxConsolidations: Coerce.number(envVars.synchronisedStorageMaxConsolidations)
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
// If there is a trusted url set, we need to add a client
|
|
1554
|
+
// and give it a feature of trusted so that when the synchronised
|
|
1555
|
+
// storage is created it can pickup the correct component
|
|
1556
|
+
if (Is.stringValue(envVars.synchronisedStorageTrustedUrl)) {
|
|
1557
|
+
coreConfig.types.synchronisedStorageComponent.push({
|
|
1558
|
+
type: SynchronisedStorageComponentType.RestClient,
|
|
1559
|
+
options: {
|
|
1560
|
+
endpoint: envVars.synchronisedStorageTrustedUrl
|
|
1561
|
+
},
|
|
1562
|
+
features: ["trusted"]
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
/**
|
|
1568
|
+
* Configures the federated catalogue.
|
|
1569
|
+
* @param coreConfig The core config.
|
|
1570
|
+
* @param envVars The environment variables.
|
|
1571
|
+
*/
|
|
1572
|
+
async function configureFederatedCatalogue(coreConfig, envVars) {
|
|
1573
|
+
if (Coerce.boolean(envVars.federatedCatalogueEnabled) ?? false) {
|
|
1574
|
+
coreConfig.types.federatedCatalogueComponent ??= [];
|
|
1575
|
+
coreConfig.types.federatedCatalogueComponent.push({
|
|
1576
|
+
type: FederatedCatalogueComponentType.Service,
|
|
1577
|
+
options: {
|
|
1578
|
+
config: {
|
|
1579
|
+
subResourceCacheTtlMs: Coerce.number(envVars.federatedCatalogueCacheTtlMs),
|
|
1580
|
+
clearingHouseApproverList: Coerce.object(envVars.federatedCatalogueClearingHouseApproverList) ?? []
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
/**
|
|
1587
|
+
* Configures the data space connector.
|
|
1588
|
+
* @param coreConfig The core config.
|
|
1589
|
+
* @param envVars The environment variables.
|
|
1590
|
+
*/
|
|
1591
|
+
async function configureDataSpaceConnector(coreConfig, envVars) {
|
|
1592
|
+
if (Coerce.boolean(envVars.dataSpaceConnectorEnabled) ?? false) {
|
|
1593
|
+
coreConfig.types.dataSpaceConnectorComponent ??= [];
|
|
1594
|
+
coreConfig.types.dataSpaceConnectorComponent.push({
|
|
1595
|
+
type: DataSpaceConnectorComponentType.Service,
|
|
1596
|
+
options: {
|
|
1597
|
+
config: {
|
|
1598
|
+
retainActivityLogsFor: Coerce.number(envVars.dataSpaceConnectorRetainActivityLogsFor),
|
|
1599
|
+
activityLogsCleanUpInterval: Coerce.number(envVars.dataSpaceConnectorActivityLogsCleanUpInterval)
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1326
1602
|
});
|
|
1327
1603
|
}
|
|
1328
1604
|
}
|
|
@@ -1331,7 +1607,7 @@ function configureTaskScheduler(coreConfig, envVars) {
|
|
|
1331
1607
|
* @param coreConfig The core config.
|
|
1332
1608
|
* @param envVars The environment variables.
|
|
1333
1609
|
*/
|
|
1334
|
-
function configureDlt(coreConfig, envVars) {
|
|
1610
|
+
async function configureDlt(coreConfig, envVars) {
|
|
1335
1611
|
// Create centralized DLT configuration for IOTA if essential IOTA variables are set
|
|
1336
1612
|
if (Is.stringValue(envVars.iotaNodeEndpoint) && Is.stringValue(envVars.iotaNetwork)) {
|
|
1337
1613
|
coreConfig.types.dltConfig ??= [];
|
|
@@ -1365,10 +1641,10 @@ function configureDlt(coreConfig, envVars) {
|
|
|
1365
1641
|
* @param coreEngineConfig The core engine config.
|
|
1366
1642
|
* @param serverInfo The server information.
|
|
1367
1643
|
* @param openApiSpecPath The path to the open api spec.
|
|
1368
|
-
* @
|
|
1644
|
+
* @param favIconPath The path to the favicon.
|
|
1645
|
+
* @returns The config for the core and the server.
|
|
1369
1646
|
*/
|
|
1370
|
-
function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath) {
|
|
1371
|
-
envVars.authSigningKeyId ??= "auth-signing";
|
|
1647
|
+
async function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, openApiSpecPath, favIconPath) {
|
|
1372
1648
|
const webServerOptions = {
|
|
1373
1649
|
port: Coerce.number(envVars.port),
|
|
1374
1650
|
host: Coerce.string(envVars.host),
|
|
@@ -1394,7 +1670,8 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1394
1670
|
options: {
|
|
1395
1671
|
config: {
|
|
1396
1672
|
serverInfo,
|
|
1397
|
-
openApiSpecPath
|
|
1673
|
+
openApiSpecPath,
|
|
1674
|
+
favIconPath
|
|
1398
1675
|
}
|
|
1399
1676
|
}
|
|
1400
1677
|
}
|
|
@@ -1414,8 +1691,9 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1414
1691
|
}
|
|
1415
1692
|
serverConfig.types.restRouteProcessor ??= [];
|
|
1416
1693
|
serverConfig.types.socketRouteProcessor ??= [];
|
|
1417
|
-
const
|
|
1418
|
-
|
|
1694
|
+
const features = getFeatures(envVars);
|
|
1695
|
+
const hasNodeIdentity = features.includes(NodeFeatures.NodeIdentity);
|
|
1696
|
+
if (hasNodeIdentity) {
|
|
1419
1697
|
serverConfig.types.restRouteProcessor.push({
|
|
1420
1698
|
type: RestRouteProcessorType.NodeIdentity
|
|
1421
1699
|
});
|
|
@@ -1424,11 +1702,18 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1424
1702
|
});
|
|
1425
1703
|
}
|
|
1426
1704
|
if (!coreEngineConfig.silent) {
|
|
1705
|
+
const includeBody = Coerce.boolean(envVars.routeLoggingIncludeBody) ?? coreEngineConfig.debug;
|
|
1706
|
+
const fullBase64 = Coerce.boolean(envVars.routeLoggingFullBase64) ?? false;
|
|
1707
|
+
const obfuscateProperties = Is.stringValue(envVars.routeLoggingObfuscateProperties)
|
|
1708
|
+
? envVars.routeLoggingObfuscateProperties.split(",")
|
|
1709
|
+
: undefined;
|
|
1427
1710
|
serverConfig.types.restRouteProcessor.push({
|
|
1428
1711
|
type: RestRouteProcessorType.Logging,
|
|
1429
1712
|
options: {
|
|
1430
1713
|
config: {
|
|
1431
|
-
includeBody
|
|
1714
|
+
includeBody,
|
|
1715
|
+
fullBase64,
|
|
1716
|
+
obfuscateProperties
|
|
1432
1717
|
}
|
|
1433
1718
|
}
|
|
1434
1719
|
});
|
|
@@ -1436,7 +1721,9 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1436
1721
|
type: SocketRouteProcessorType.Logging,
|
|
1437
1722
|
options: {
|
|
1438
1723
|
config: {
|
|
1439
|
-
includeBody
|
|
1724
|
+
includeBody,
|
|
1725
|
+
fullBase64,
|
|
1726
|
+
obfuscateProperties
|
|
1440
1727
|
}
|
|
1441
1728
|
}
|
|
1442
1729
|
});
|
|
@@ -1474,7 +1761,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1474
1761
|
type: AuthenticationComponentType.EntityStorage,
|
|
1475
1762
|
options: {
|
|
1476
1763
|
config: {
|
|
1477
|
-
signingKeyName: envVars.authSigningKeyId
|
|
1764
|
+
signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
|
|
1478
1765
|
}
|
|
1479
1766
|
}
|
|
1480
1767
|
});
|
|
@@ -1482,7 +1769,7 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1482
1769
|
type: RestRouteProcessorType.AuthHeader,
|
|
1483
1770
|
options: {
|
|
1484
1771
|
config: {
|
|
1485
|
-
signingKeyName: envVars.authSigningKeyId
|
|
1772
|
+
signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
|
|
1486
1773
|
}
|
|
1487
1774
|
}
|
|
1488
1775
|
});
|
|
@@ -1490,11 +1777,19 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1490
1777
|
type: SocketRouteProcessorType.AuthHeader,
|
|
1491
1778
|
options: {
|
|
1492
1779
|
config: {
|
|
1493
|
-
signingKeyName: envVars.authSigningKeyId
|
|
1780
|
+
signingKeyName: envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID
|
|
1494
1781
|
}
|
|
1495
1782
|
}
|
|
1496
1783
|
});
|
|
1497
1784
|
}
|
|
1785
|
+
if (Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) {
|
|
1786
|
+
serverConfig.types.restRouteProcessor.push({
|
|
1787
|
+
type: RestRouteProcessorType.AuthVerifiableCredential
|
|
1788
|
+
});
|
|
1789
|
+
serverConfig.types.socketRouteProcessor.push({
|
|
1790
|
+
type: SocketRouteProcessorType.AuthVerifiableCredential
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1498
1793
|
addDefaultRestPaths(serverConfig);
|
|
1499
1794
|
addDefaultSocketPaths(serverConfig);
|
|
1500
1795
|
return serverConfig;
|
|
@@ -1502,18 +1797,115 @@ function buildEngineServerConfiguration(envVars, coreEngineConfig, serverInfo, o
|
|
|
1502
1797
|
|
|
1503
1798
|
// Copyright 2024 IOTA Stiftung.
|
|
1504
1799
|
// SPDX-License-Identifier: Apache-2.0.
|
|
1505
|
-
|
|
1800
|
+
/**
|
|
1801
|
+
* Handles the configuration of the extensions.
|
|
1802
|
+
* @param envVars The environment variables for the node.
|
|
1803
|
+
* @param nodeEngineConfig The node engine config.
|
|
1804
|
+
* @returns The config for the core and the server.
|
|
1805
|
+
*/
|
|
1806
|
+
async function extensionsConfiguration(envVars, nodeEngineConfig) {
|
|
1807
|
+
if (Is.stringValue(envVars.extensions)) {
|
|
1808
|
+
const extensions = envVars.extensions.split(",");
|
|
1809
|
+
for (const extension of extensions) {
|
|
1810
|
+
let initialiseConfigMethod;
|
|
1811
|
+
try {
|
|
1812
|
+
CLIDisplay.value(I18n.formatMessage("node.extensionLoading"), extension);
|
|
1813
|
+
initialiseConfigMethod = await ModuleHelper.getModuleMethod(extension, "extensionInitialise");
|
|
1814
|
+
}
|
|
1815
|
+
catch (err) {
|
|
1816
|
+
throw new GeneralError("node", "extensionLoadingError", { extension }, err);
|
|
1817
|
+
}
|
|
1818
|
+
if (Is.function(initialiseConfigMethod)) {
|
|
1819
|
+
await initialiseConfigMethod(envVars, nodeEngineConfig);
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
return nodeEngineConfig;
|
|
1824
|
+
}
|
|
1825
|
+
/**
|
|
1826
|
+
* Handles the initialisation of the extensions when the engine has been constructed.
|
|
1827
|
+
* @param envVars The environment variables for the node.
|
|
1828
|
+
* @param engineCore The engine core instance.
|
|
1829
|
+
* @returns Nothing.
|
|
1830
|
+
*/
|
|
1831
|
+
async function extensionsInitialiseEngine(envVars, engineCore) {
|
|
1832
|
+
if (Is.stringValue(envVars.extensions)) {
|
|
1833
|
+
const extensions = envVars.extensions.split(",");
|
|
1834
|
+
for (const extension of extensions) {
|
|
1835
|
+
let initialiseEngineMethod;
|
|
1836
|
+
try {
|
|
1837
|
+
engineCore.logInfo(I18n.formatMessage("node.extensionInitialisingEngine", { extension }));
|
|
1838
|
+
initialiseEngineMethod =
|
|
1839
|
+
await ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngine");
|
|
1840
|
+
}
|
|
1841
|
+
catch { }
|
|
1842
|
+
if (Is.function(initialiseEngineMethod)) {
|
|
1843
|
+
await initialiseEngineMethod(engineCore);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Handles the initialisation of the extensions when the engine server has been constructed.
|
|
1850
|
+
* @param envVars The environment variables for the node.
|
|
1851
|
+
* @param engineCore The engine core instance.
|
|
1852
|
+
* @param engineServer The engine server instance.
|
|
1853
|
+
* @returns Nothing.
|
|
1854
|
+
*/
|
|
1855
|
+
async function extensionsInitialiseEngineServer(envVars, engineCore, engineServer) {
|
|
1856
|
+
if (Is.stringValue(envVars.extensions)) {
|
|
1857
|
+
const extensions = envVars.extensions.split(",");
|
|
1858
|
+
for (const extension of extensions) {
|
|
1859
|
+
let initialiseEngineServerMethod;
|
|
1860
|
+
try {
|
|
1861
|
+
engineCore.logInfo(I18n.formatMessage("node.extensionInitialisingEngineServer", { extension }));
|
|
1862
|
+
initialiseEngineServerMethod =
|
|
1863
|
+
await ModuleHelper.getModuleMethod(extension, "extensionInitialiseEngineServer");
|
|
1864
|
+
}
|
|
1865
|
+
catch { }
|
|
1866
|
+
if (Is.function(initialiseEngineServerMethod)) {
|
|
1867
|
+
await initialiseEngineServerMethod(engineCore, engineServer);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Handles the shutdown of the extensions.
|
|
1874
|
+
* @param envVars The environment variables for the node.
|
|
1875
|
+
* @param engineCore The engine core instance.
|
|
1876
|
+
* @returns Nothing.
|
|
1877
|
+
*/
|
|
1878
|
+
async function shutdownExtensions(envVars, engineCore) {
|
|
1879
|
+
if (Is.stringValue(envVars.extensions)) {
|
|
1880
|
+
const extensions = envVars.extensions.split(",");
|
|
1881
|
+
for (const extension of extensions) {
|
|
1882
|
+
let shutdownMethod;
|
|
1883
|
+
try {
|
|
1884
|
+
engineCore.logInfo(I18n.formatMessage("node.extensionShutdown", { extension }));
|
|
1885
|
+
shutdownMethod = await ModuleHelper.getModuleMethod(extension, "extensionShutdown");
|
|
1886
|
+
}
|
|
1887
|
+
catch { }
|
|
1888
|
+
if (Is.function(shutdownMethod)) {
|
|
1889
|
+
await shutdownMethod();
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
// Copyright 2024 IOTA Stiftung.
|
|
1896
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
1506
1897
|
/**
|
|
1507
1898
|
* Start the engine server.
|
|
1508
1899
|
* @param nodeOptions Optional run options for the engine server.
|
|
1509
|
-
* @param
|
|
1900
|
+
* @param nodeEngineConfig The configuration for the engine server.
|
|
1510
1901
|
* @param envVars The environment variables.
|
|
1511
1902
|
* @returns The engine server.
|
|
1512
1903
|
*/
|
|
1513
|
-
async function start(nodeOptions,
|
|
1514
|
-
envVars.storageFileRoot ??= "";
|
|
1904
|
+
async function start(nodeOptions, nodeEngineConfig, envVars) {
|
|
1515
1905
|
const entityStorageConnectorType = envVars.entityStorageConnectorType?.split(",") ?? [];
|
|
1516
1906
|
const blobStorageConnectorType = envVars.blobStorageConnectorType?.split(",") ?? [];
|
|
1907
|
+
// If the blob storage or entity storage is configured with file connectors
|
|
1908
|
+
// then we need to make sure the storageFileRoot is set
|
|
1517
1909
|
if ((entityStorageConnectorType.includes(EntityStorageConnectorType.File) ||
|
|
1518
1910
|
blobStorageConnectorType.includes(BlobStorageConnectorType.File) ||
|
|
1519
1911
|
Is.empty(nodeOptions?.stateStorage)) &&
|
|
@@ -1522,24 +1914,26 @@ async function start(nodeOptions, engineServerConfig, envVars) {
|
|
|
1522
1914
|
storageFileRoot: `${nodeOptions?.envPrefix ?? ""}_STORAGE_FILE_ROOT`
|
|
1523
1915
|
});
|
|
1524
1916
|
}
|
|
1525
|
-
// Create the engine instance using file state storage
|
|
1917
|
+
// Create the engine instance using file state storage unless one is configured in options
|
|
1526
1918
|
const engine = new Engine({
|
|
1527
|
-
config:
|
|
1919
|
+
config: nodeEngineConfig,
|
|
1528
1920
|
stateStorage: nodeOptions?.stateStorage ?? new FileStateStorage(envVars.stateFilename ?? ""),
|
|
1529
1921
|
customBootstrap: async (core, engineContext) => bootstrap(core, engineContext, envVars)
|
|
1530
1922
|
});
|
|
1923
|
+
// Construct the server with the engine.
|
|
1924
|
+
const server = new EngineServer({ engineCore: engine });
|
|
1531
1925
|
// Extend the engine.
|
|
1532
1926
|
if (Is.function(nodeOptions?.extendEngine)) {
|
|
1533
|
-
|
|
1927
|
+
engine.logInfo(I18n.formatMessage("node.extendingEngine"));
|
|
1534
1928
|
await nodeOptions.extendEngine(engine);
|
|
1535
1929
|
}
|
|
1536
|
-
|
|
1537
|
-
const server = new EngineServer({ engineCore: engine });
|
|
1930
|
+
await extensionsInitialiseEngine(envVars, engine);
|
|
1538
1931
|
// Extend the engine server.
|
|
1539
1932
|
if (Is.function(nodeOptions?.extendEngineServer)) {
|
|
1540
|
-
|
|
1933
|
+
engine.logInfo(I18n.formatMessage("node.extendingEngineServer"));
|
|
1541
1934
|
await nodeOptions?.extendEngineServer(server);
|
|
1542
1935
|
}
|
|
1936
|
+
await extensionsInitialiseEngineServer(envVars, engine, server);
|
|
1543
1937
|
// Need to register the engine with the factory so that background tasks
|
|
1544
1938
|
// can clone it to spawn new instances.
|
|
1545
1939
|
EngineCoreFactory.register("engine", () => engine);
|
|
@@ -1548,14 +1942,17 @@ async function start(nodeOptions, engineServerConfig, envVars) {
|
|
|
1548
1942
|
if (canContinue) {
|
|
1549
1943
|
return {
|
|
1550
1944
|
engine,
|
|
1551
|
-
server
|
|
1945
|
+
server,
|
|
1946
|
+
shutdown: async () => {
|
|
1947
|
+
await server.stop();
|
|
1948
|
+
await shutdownExtensions(envVars, engine);
|
|
1949
|
+
}
|
|
1552
1950
|
};
|
|
1553
1951
|
}
|
|
1554
1952
|
}
|
|
1555
1953
|
|
|
1556
1954
|
// Copyright 2024 IOTA Stiftung.
|
|
1557
1955
|
// SPDX-License-Identifier: Apache-2.0.
|
|
1558
|
-
/* eslint-disable no-console */
|
|
1559
1956
|
/**
|
|
1560
1957
|
* Run the TWIN Node server.
|
|
1561
1958
|
* @param nodeOptions Optional configuration options for running the server.
|
|
@@ -1566,41 +1963,59 @@ async function run(nodeOptions) {
|
|
|
1566
1963
|
nodeOptions ??= {};
|
|
1567
1964
|
const serverInfo = {
|
|
1568
1965
|
name: nodeOptions?.serverName ?? "TWIN Node Server",
|
|
1569
|
-
version: nodeOptions?.serverVersion ?? "0.0.2-next.
|
|
1966
|
+
version: nodeOptions?.serverVersion ?? "0.0.2-next.20" // x-release-please-version
|
|
1570
1967
|
};
|
|
1571
|
-
|
|
1968
|
+
CLIDisplay.header(serverInfo.name, serverInfo.version, "🌩️ ");
|
|
1572
1969
|
if (!Is.stringValue(nodeOptions?.executionDirectory)) {
|
|
1573
1970
|
nodeOptions.executionDirectory = getExecutionDirectory();
|
|
1574
1971
|
}
|
|
1575
|
-
|
|
1972
|
+
CLIDisplay.value("Execution Directory", nodeOptions.executionDirectory);
|
|
1576
1973
|
nodeOptions.localesDirectory =
|
|
1577
1974
|
nodeOptions?.localesDirectory ??
|
|
1578
1975
|
path.resolve(path.join(nodeOptions.executionDirectory, "dist", "locales"));
|
|
1579
|
-
|
|
1976
|
+
CLIDisplay.value("Locales Directory", nodeOptions.localesDirectory);
|
|
1580
1977
|
await initialiseLocales(nodeOptions.localesDirectory);
|
|
1581
1978
|
if (Is.empty(nodeOptions?.openApiSpecFile)) {
|
|
1582
|
-
const specFile = path.resolve(path.join(nodeOptions.executionDirectory, "docs", "open-api", "spec.json"));
|
|
1583
|
-
|
|
1979
|
+
const specFile = path.resolve(path.join(nodeOptions.executionDirectory ?? "", "docs", "open-api", "spec.json"));
|
|
1980
|
+
CLIDisplay.value("Default OpenAPI Spec File", specFile);
|
|
1584
1981
|
if (await fileExists(specFile)) {
|
|
1585
1982
|
nodeOptions ??= {};
|
|
1586
1983
|
nodeOptions.openApiSpecFile = specFile;
|
|
1587
1984
|
}
|
|
1588
1985
|
}
|
|
1986
|
+
else {
|
|
1987
|
+
CLIDisplay.value("OpenAPI Spec File", nodeOptions.openApiSpecFile);
|
|
1988
|
+
}
|
|
1989
|
+
if (Is.empty(nodeOptions?.favIconFile)) {
|
|
1990
|
+
const favIconFile = path.resolve(path.join(nodeOptions.executionDirectory ?? "", "static", "favicon.png"));
|
|
1991
|
+
CLIDisplay.value("Default Favicon File", favIconFile);
|
|
1992
|
+
if (await fileExists(favIconFile)) {
|
|
1993
|
+
nodeOptions ??= {};
|
|
1994
|
+
nodeOptions.favIconFile = favIconFile;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
else {
|
|
1998
|
+
CLIDisplay.value("Favicon File", nodeOptions.favIconFile);
|
|
1999
|
+
}
|
|
1589
2000
|
nodeOptions.envPrefix ??= "TWIN_NODE_";
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
2001
|
+
CLIDisplay.value("Environment Variable Prefix", nodeOptions.envPrefix);
|
|
2002
|
+
overrideModuleImport(nodeOptions.executionDirectory ?? "");
|
|
2003
|
+
const { nodeEngineConfig, nodeEnvVars: envVars } = await buildConfiguration(
|
|
2004
|
+
// This is the only location in the code base that should access process.env directly
|
|
2005
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
2006
|
+
process.env, nodeOptions, serverInfo);
|
|
2007
|
+
CLIDisplay.break();
|
|
2008
|
+
const startResult = await start(nodeOptions, nodeEngineConfig, envVars);
|
|
1594
2009
|
if (!Is.empty(startResult)) {
|
|
1595
2010
|
for (const signal of ["SIGHUP", "SIGINT", "SIGTERM"]) {
|
|
1596
2011
|
process.on(signal, async () => {
|
|
1597
|
-
await startResult.
|
|
2012
|
+
await startResult.shutdown();
|
|
1598
2013
|
});
|
|
1599
2014
|
}
|
|
1600
2015
|
}
|
|
1601
2016
|
}
|
|
1602
2017
|
catch (err) {
|
|
1603
|
-
|
|
2018
|
+
CLIDisplay.error(err);
|
|
1604
2019
|
// eslint-disable-next-line unicorn/no-process-exit
|
|
1605
2020
|
process.exit(1);
|
|
1606
2021
|
}
|
|
@@ -1617,14 +2032,15 @@ async function buildConfiguration(processEnv, options, serverInfo) {
|
|
|
1617
2032
|
let defaultEnvOnly = false;
|
|
1618
2033
|
if (Is.empty(options?.envFilenames)) {
|
|
1619
2034
|
const envFile = path.resolve(path.join(options.executionDirectory ?? "", ".env"));
|
|
1620
|
-
|
|
2035
|
+
CLIDisplay.value("Default Environment File", envFile);
|
|
1621
2036
|
options ??= {};
|
|
1622
2037
|
options.envFilenames = [envFile];
|
|
1623
2038
|
defaultEnvOnly = true;
|
|
1624
2039
|
}
|
|
1625
2040
|
if (Is.arrayValue(options?.envFilenames)) {
|
|
1626
2041
|
const output = dotenv.config({
|
|
1627
|
-
path: options?.envFilenames
|
|
2042
|
+
path: options?.envFilenames,
|
|
2043
|
+
quiet: true
|
|
1628
2044
|
});
|
|
1629
2045
|
// We don't want to throw an error if the default environment file is not found.
|
|
1630
2046
|
// Only if we have custom environment files.
|
|
@@ -1639,41 +2055,82 @@ async function buildConfiguration(processEnv, options, serverInfo) {
|
|
|
1639
2055
|
// Expand any environment variables that use the @file: syntax
|
|
1640
2056
|
const keys = Object.keys(envVars);
|
|
1641
2057
|
for (const key of keys) {
|
|
1642
|
-
if (Is.stringValue(envVars[key]) &&
|
|
2058
|
+
if (Is.stringValue(envVars[key]) &&
|
|
2059
|
+
(envVars[key].startsWith("@text:") || envVars[key].startsWith("@json:"))) {
|
|
1643
2060
|
const filePath = envVars[key].slice(6).trim();
|
|
1644
2061
|
const embeddedFile = path.resolve(path.join(options.executionDirectory ?? "", filePath));
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
2062
|
+
if (envVars[key].startsWith("@text:")) {
|
|
2063
|
+
CLIDisplay.value(`Expanding Environment Variable: ${key} from text file`, embeddedFile);
|
|
2064
|
+
envVars[key] = await loadTextFile(embeddedFile);
|
|
2065
|
+
}
|
|
2066
|
+
else if (envVars[key].startsWith("@json:")) {
|
|
2067
|
+
CLIDisplay.value(`Expanding Environment Variable: ${key} from JSON file`, embeddedFile);
|
|
2068
|
+
envVars[key] = await loadJsonFile(embeddedFile);
|
|
2069
|
+
}
|
|
1648
2070
|
}
|
|
1649
2071
|
}
|
|
1650
2072
|
// Extend the environment variables with any additional custom configuration.
|
|
1651
2073
|
if (Is.function(options?.extendEnvVars)) {
|
|
1652
|
-
|
|
2074
|
+
CLIDisplay.task("Extending Environment Variables");
|
|
1653
2075
|
await options.extendEnvVars(envVars);
|
|
1654
2076
|
}
|
|
1655
2077
|
// Build the engine configuration from the environment variables.
|
|
1656
|
-
const coreConfig = buildEngineConfiguration(envVars);
|
|
1657
|
-
const engineServerConfig = buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile);
|
|
2078
|
+
const coreConfig = await buildEngineConfiguration(envVars);
|
|
2079
|
+
const engineServerConfig = await buildEngineServerConfiguration(envVars, coreConfig, serverInfo, options?.openApiSpecFile, options?.favIconFile);
|
|
1658
2080
|
// Merge any custom configuration provided in the options.
|
|
1659
2081
|
if (Is.arrayValue(options?.configFilenames)) {
|
|
1660
2082
|
for (const configFile of options.configFilenames) {
|
|
1661
|
-
|
|
2083
|
+
CLIDisplay.value("Loading Configuration File", configFile);
|
|
1662
2084
|
const configFilePath = path.resolve(path.join(options.executionDirectory ?? "", configFile));
|
|
1663
2085
|
const config = await loadJsonFile(configFilePath);
|
|
1664
2086
|
Object.assign(engineServerConfig, config);
|
|
1665
2087
|
}
|
|
1666
2088
|
}
|
|
1667
2089
|
if (Is.objectValue(options?.config)) {
|
|
1668
|
-
|
|
2090
|
+
CLIDisplay.task("Merging Custom Configuration");
|
|
1669
2091
|
Object.assign(engineServerConfig, options.config);
|
|
1670
2092
|
}
|
|
1671
2093
|
// Merge any custom configuration provided in the options.
|
|
1672
2094
|
if (Is.function(options?.extendConfig)) {
|
|
1673
|
-
|
|
1674
|
-
await options.extendConfig(engineServerConfig);
|
|
2095
|
+
CLIDisplay.task("Extending Configuration");
|
|
2096
|
+
await options.extendConfig(envVars, engineServerConfig);
|
|
1675
2097
|
}
|
|
1676
|
-
|
|
2098
|
+
const nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);
|
|
2099
|
+
return { nodeEngineConfig, nodeEnvVars: envVars };
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Override module imports to use local files where possible.
|
|
2103
|
+
* @param executionDirectory The execution directory for resolving local module paths.
|
|
2104
|
+
*/
|
|
2105
|
+
function overrideModuleImport(executionDirectory) {
|
|
2106
|
+
ModuleHelper.overrideImport(async (moduleName) => {
|
|
2107
|
+
// If the module path for example when dynamically loading
|
|
2108
|
+
// modules looks like a local file then we try to resolve
|
|
2109
|
+
// using the local file system
|
|
2110
|
+
const isLocal = ModuleHelper.isLocalModule(moduleName);
|
|
2111
|
+
if (isLocal) {
|
|
2112
|
+
// See if we can just resolve the filename locally
|
|
2113
|
+
let localFilename = path.resolve(moduleName);
|
|
2114
|
+
let exists = await fileExists(localFilename);
|
|
2115
|
+
if (!exists) {
|
|
2116
|
+
// Doesn't exist in the current directory, try the execution directory
|
|
2117
|
+
localFilename = path.resolve(executionDirectory, moduleName);
|
|
2118
|
+
exists = await fileExists(localFilename);
|
|
2119
|
+
}
|
|
2120
|
+
if (exists) {
|
|
2121
|
+
// If the module exists then we can load it, otherwise
|
|
2122
|
+
// we fallback to regular handling to see if that can import it
|
|
2123
|
+
return {
|
|
2124
|
+
module: await import(process.platform === "win32" ? `file://${localFilename}` : localFilename),
|
|
2125
|
+
useDefault: false
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
// The filename doesn't look like a local module, so just use default handling
|
|
2130
|
+
return {
|
|
2131
|
+
useDefault: true
|
|
2132
|
+
};
|
|
2133
|
+
});
|
|
1677
2134
|
}
|
|
1678
2135
|
|
|
1679
|
-
export { NodeFeatures,
|
|
2136
|
+
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 };
|