@twin.org/node-core 0.0.3-next.9 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/README.md +3 -1
  2. package/dist/es/builders/engineEnvBuilder.js +470 -174
  3. package/dist/es/builders/engineEnvBuilder.js.map +1 -1
  4. package/dist/es/builders/engineServerEnvBuilder.js +87 -39
  5. package/dist/es/builders/engineServerEnvBuilder.js.map +1 -1
  6. package/dist/es/builders/extensionsBuilder.js +3 -3
  7. package/dist/es/builders/extensionsBuilder.js.map +1 -1
  8. package/dist/es/cli.js +254 -0
  9. package/dist/es/cli.js.map +1 -0
  10. package/dist/es/commands/bootstrapLegacy.js +312 -0
  11. package/dist/es/commands/bootstrapLegacy.js.map +1 -0
  12. package/dist/es/commands/help.js +86 -0
  13. package/dist/es/commands/help.js.map +1 -0
  14. package/dist/es/commands/identityCreate.js +377 -0
  15. package/dist/es/commands/identityCreate.js.map +1 -0
  16. package/dist/es/commands/identityImports.js +83 -0
  17. package/dist/es/commands/identityImports.js.map +1 -0
  18. package/dist/es/commands/identityVerifiableCredentialCreate.js +146 -0
  19. package/dist/es/commands/identityVerifiableCredentialCreate.js.map +1 -0
  20. package/dist/es/commands/identityVerificationMethodCreate.js +231 -0
  21. package/dist/es/commands/identityVerificationMethodCreate.js.map +1 -0
  22. package/dist/es/commands/identityVerificationMethodImport.js +127 -0
  23. package/dist/es/commands/identityVerificationMethodImport.js.map +1 -0
  24. package/dist/es/commands/nodeSetIdentity.js +69 -0
  25. package/dist/es/commands/nodeSetIdentity.js.map +1 -0
  26. package/dist/es/commands/removeTenantOrgAlias.js +83 -0
  27. package/dist/es/commands/removeTenantOrgAlias.js.map +1 -0
  28. package/dist/es/commands/setNodeOrgId.js +62 -0
  29. package/dist/es/commands/setNodeOrgId.js.map +1 -0
  30. package/dist/es/commands/setTenantOrgId.js +99 -0
  31. package/dist/es/commands/setTenantOrgId.js.map +1 -0
  32. package/dist/es/commands/tenantCreate.js +165 -0
  33. package/dist/es/commands/tenantCreate.js.map +1 -0
  34. package/dist/es/commands/tenantImport.js +108 -0
  35. package/dist/es/commands/tenantImport.js.map +1 -0
  36. package/dist/es/commands/tenantUpdate.js +108 -0
  37. package/dist/es/commands/tenantUpdate.js.map +1 -0
  38. package/dist/es/commands/userCreate.js +239 -0
  39. package/dist/es/commands/userCreate.js.map +1 -0
  40. package/dist/es/commands/userUpdate.js +154 -0
  41. package/dist/es/commands/userUpdate.js.map +1 -0
  42. package/dist/es/commands/vaultKeyCreate.js +191 -0
  43. package/dist/es/commands/vaultKeyCreate.js.map +1 -0
  44. package/dist/es/commands/vaultKeyImport.js +105 -0
  45. package/dist/es/commands/vaultKeyImport.js.map +1 -0
  46. package/dist/es/defaults.js +37 -2
  47. package/dist/es/defaults.js.map +1 -1
  48. package/dist/es/index.js +13 -4
  49. package/dist/es/index.js.map +1 -1
  50. package/dist/es/models/IBootstrapLegacyEnvironmentVariables.js +4 -0
  51. package/dist/es/models/IBootstrapLegacyEnvironmentVariables.js.map +1 -0
  52. package/dist/es/models/ICliArgs.js +4 -0
  53. package/dist/es/models/ICliArgs.js.map +1 -0
  54. package/dist/es/models/ICliCommand.js +2 -0
  55. package/dist/es/models/ICliCommand.js.map +1 -0
  56. package/dist/es/models/ICliCommandDefinition.js +2 -0
  57. package/dist/es/models/ICliCommandDefinition.js.map +1 -0
  58. package/dist/es/models/ICliCommandDefinitionParam.js +2 -0
  59. package/dist/es/models/ICliCommandDefinitionParam.js.map +1 -0
  60. package/dist/es/models/IEngineEnvironmentVariables.js.map +1 -1
  61. package/dist/es/models/IEngineServerEnvironmentVariables.js +2 -0
  62. package/dist/es/models/IEngineServerEnvironmentVariables.js.map +1 -1
  63. package/dist/es/models/IEnvironmentVariables.js +2 -0
  64. package/dist/es/models/IEnvironmentVariables.js.map +1 -0
  65. package/dist/es/models/INodeEngineState.js.map +1 -1
  66. package/dist/es/models/INodeEnvironmentVariables.js +2 -0
  67. package/dist/es/models/INodeEnvironmentVariables.js.map +1 -1
  68. package/dist/es/models/INodeOptions.js.map +1 -1
  69. package/dist/es/models/bootstrapLegacyEnvironmentVariableKeys.js +24 -0
  70. package/dist/es/models/bootstrapLegacyEnvironmentVariableKeys.js.map +1 -0
  71. package/dist/es/models/cliCommandParamType.js +4 -0
  72. package/dist/es/models/cliCommandParamType.js.map +1 -0
  73. package/dist/es/models/engineEnvironmentVariableKeys.js +202 -0
  74. package/dist/es/models/engineEnvironmentVariableKeys.js.map +1 -0
  75. package/dist/es/models/engineServerEnvironmentVariableKeys.js +35 -0
  76. package/dist/es/models/engineServerEnvironmentVariableKeys.js.map +1 -0
  77. package/dist/es/models/nodeEnvironmentVariableKeys.js +18 -0
  78. package/dist/es/models/nodeEnvironmentVariableKeys.js.map +1 -0
  79. package/dist/es/models/nodeExtensionInitialiseEngineMethod.js +2 -0
  80. package/dist/es/models/nodeExtensionInitialiseEngineMethod.js.map +1 -0
  81. package/dist/es/models/nodeExtensionInitialiseEngineServerMethod.js +2 -0
  82. package/dist/es/models/nodeExtensionInitialiseEngineServerMethod.js.map +1 -0
  83. package/dist/es/models/nodeExtensionInitialiseMethod.js +2 -0
  84. package/dist/es/models/nodeExtensionInitialiseMethod.js.map +1 -0
  85. package/dist/es/models/nodeExtensionShutdownMethod.js +4 -0
  86. package/dist/es/models/nodeExtensionShutdownMethod.js.map +1 -0
  87. package/dist/es/node.js +180 -42
  88. package/dist/es/node.js.map +1 -1
  89. package/dist/es/start.js +189 -0
  90. package/dist/es/start.js.map +1 -0
  91. package/dist/es/utils.js +24 -27
  92. package/dist/es/utils.js.map +1 -1
  93. package/dist/types/builders/engineEnvBuilder.d.ts +60 -5
  94. package/dist/types/builders/engineServerEnvBuilder.d.ts +12 -3
  95. package/dist/types/builders/extensionsBuilder.d.ts +8 -8
  96. package/dist/types/cli.d.ts +56 -0
  97. package/dist/types/commands/bootstrapLegacy.d.ts +20 -0
  98. package/dist/types/commands/help.d.ts +24 -0
  99. package/dist/types/commands/identityCreate.d.ts +45 -0
  100. package/dist/types/commands/identityImports.d.ts +25 -0
  101. package/dist/types/commands/identityVerifiableCredentialCreate.d.ts +43 -0
  102. package/dist/types/commands/identityVerificationMethodCreate.d.ts +47 -0
  103. package/dist/types/commands/identityVerificationMethodImport.d.ts +32 -0
  104. package/dist/types/commands/nodeSetIdentity.d.ts +23 -0
  105. package/dist/types/commands/removeTenantOrgAlias.d.ts +24 -0
  106. package/dist/types/commands/setNodeOrgId.d.ts +24 -0
  107. package/dist/types/commands/setTenantOrgId.d.ts +38 -0
  108. package/dist/types/commands/tenantCreate.d.ts +41 -0
  109. package/dist/types/commands/tenantImport.d.ts +29 -0
  110. package/dist/types/commands/tenantUpdate.d.ts +29 -0
  111. package/dist/types/commands/userCreate.d.ts +51 -0
  112. package/dist/types/commands/userUpdate.d.ts +40 -0
  113. package/dist/types/commands/vaultKeyCreate.d.ts +43 -0
  114. package/dist/types/commands/vaultKeyImport.d.ts +29 -0
  115. package/dist/types/defaults.d.ts +30 -2
  116. package/dist/types/index.d.ts +13 -4
  117. package/dist/types/models/IBootstrapLegacyEnvironmentVariables.d.ts +56 -0
  118. package/dist/types/models/ICliArgs.d.ts +20 -0
  119. package/dist/types/models/ICliCommand.d.ts +17 -0
  120. package/dist/types/models/ICliCommandDefinition.d.ts +46 -0
  121. package/dist/types/models/ICliCommandDefinitionParam.d.ts +35 -0
  122. package/dist/types/models/IEngineEnvironmentVariables.d.ts +199 -96
  123. package/dist/types/models/IEngineServerEnvironmentVariables.d.ts +9 -2
  124. package/dist/types/models/IEnvironmentVariables.d.ts +8 -0
  125. package/dist/types/models/INodeEngineState.d.ts +2 -9
  126. package/dist/types/models/INodeEnvironmentVariables.d.ts +1 -40
  127. package/dist/types/models/INodeOptions.d.ts +9 -5
  128. package/dist/types/models/bootstrapLegacyEnvironmentVariableKeys.d.ts +4 -0
  129. package/dist/types/models/cliCommandParamType.d.ts +4 -0
  130. package/dist/types/models/engineEnvironmentVariableKeys.d.ts +4 -0
  131. package/dist/types/models/engineServerEnvironmentVariableKeys.d.ts +7 -0
  132. package/dist/types/models/nodeEnvironmentVariableKeys.d.ts +5 -0
  133. package/dist/types/models/nodeExtensionInitialiseEngineMethod.d.ts +8 -0
  134. package/dist/types/models/nodeExtensionInitialiseEngineServerMethod.d.ts +9 -0
  135. package/dist/types/models/nodeExtensionInitialiseMethod.d.ts +9 -0
  136. package/dist/types/models/nodeExtensionShutdownMethod.d.ts +6 -0
  137. package/dist/types/node.d.ts +8 -7
  138. package/dist/types/{server.d.ts → start.d.ts} +6 -3
  139. package/dist/types/utils.d.ts +9 -10
  140. package/docs/changelog.md +883 -186
  141. package/docs/examples.md +99 -1
  142. package/docs/reference/functions/buildConfiguration.md +3 -3
  143. package/docs/reference/functions/buildEngineConfiguration.md +1 -7
  144. package/docs/reference/functions/buildEngineServerConfiguration.md +1 -1
  145. package/docs/reference/functions/constructCliCommand.md +27 -0
  146. package/docs/reference/functions/executeCommand.md +29 -0
  147. package/docs/reference/functions/extensionsConfiguration.md +1 -1
  148. package/docs/reference/functions/extensionsInitialiseEngine.md +2 -2
  149. package/docs/reference/functions/extensionsInitialiseEngineServer.md +2 -2
  150. package/docs/reference/functions/getEnvDefaults.md +19 -0
  151. package/docs/reference/functions/getScriptDirectory.md +19 -0
  152. package/docs/reference/functions/initialiseLocales.md +2 -0
  153. package/docs/reference/functions/isAuthEntityStorageRequired.md +20 -0
  154. package/docs/reference/functions/isAutomationRequired.md +20 -0
  155. package/docs/reference/functions/isBackgroundTasksRequired.md +20 -0
  156. package/docs/reference/functions/isFederatedCatalogueRequired.md +20 -0
  157. package/docs/reference/functions/isImmutableProofRequired.md +20 -0
  158. package/docs/reference/functions/isRightsManagementRequired.md +23 -0
  159. package/docs/reference/functions/isTaskSchedulerRequired.md +20 -0
  160. package/docs/reference/functions/isTelemetryRequired.md +20 -0
  161. package/docs/reference/functions/isTrustRequired.md +20 -0
  162. package/docs/reference/functions/loadJsonFile.md +1 -1
  163. package/docs/reference/functions/loadTextFile.md +1 -1
  164. package/docs/reference/functions/overrideModuleImport.md +1 -1
  165. package/docs/reference/functions/parseCommandLineArgs.md +19 -0
  166. package/docs/reference/functions/processEnvOptions.md +27 -0
  167. package/docs/reference/functions/registerCommands.md +9 -0
  168. package/docs/reference/functions/resolvePackageEntryPoint.md +2 -2
  169. package/docs/reference/functions/run.md +8 -2
  170. package/docs/reference/functions/shutdownExtensions.md +2 -2
  171. package/docs/reference/functions/start.md +10 -4
  172. package/docs/reference/functions/substituteEnvOptions.md +25 -0
  173. package/docs/reference/index.md +26 -14
  174. package/docs/reference/interfaces/IBootstrapLegacyEnvironmentVariables.md +117 -0
  175. package/docs/reference/interfaces/ICacheMetadata.md +3 -3
  176. package/docs/reference/interfaces/ICliArgs.md +35 -0
  177. package/docs/reference/interfaces/ICliCommand.md +23 -0
  178. package/docs/reference/interfaces/ICliCommandDefinition.md +101 -0
  179. package/docs/reference/interfaces/ICliCommandDefinitionParam.md +65 -0
  180. package/docs/reference/interfaces/IEngineEnvironmentVariables.md +553 -365
  181. package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +41 -1746
  182. package/docs/reference/interfaces/IModuleProtocol.md +3 -3
  183. package/docs/reference/interfaces/INodeEngineState.md +6 -21
  184. package/docs/reference/interfaces/INodeEnvironmentVariables.md +10 -1967
  185. package/docs/reference/interfaces/INodeOptions.md +46 -38
  186. package/docs/reference/interfaces/IProtocolHandlerResult.md +2 -2
  187. package/docs/reference/type-aliases/CliCommandParamType.md +5 -0
  188. package/docs/reference/type-aliases/IEnvironmentVariables.md +5 -0
  189. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineMethod.md +3 -1
  190. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineServerMethod.md +3 -1
  191. package/docs/reference/type-aliases/NodeExtensionInitialiseMethod.md +4 -2
  192. package/docs/reference/type-aliases/NodeExtensionShutdownMethod.md +3 -1
  193. package/docs/reference/variables/ATTESTATION_VERIFICATION_METHOD_ID.md +2 -0
  194. package/docs/reference/variables/AUTH_SIGNING_KEY_ID.md +2 -0
  195. package/docs/reference/variables/BLOB_STORAGE_ENCRYPTION_KEY_ID.md +2 -0
  196. package/docs/reference/variables/CONTEXT_ID_HANDLER_FEATURE_DID.md +2 -0
  197. package/docs/reference/variables/CONTEXT_ID_HANDLER_FEATURE_TENANT.md +2 -0
  198. package/docs/reference/variables/IMMUTABLE_PROOF_VERIFICATION_METHOD_ID.md +2 -0
  199. package/docs/reference/variables/ModuleProtocol.md +5 -5
  200. package/docs/reference/variables/TRUST_VERIFICATION_METHOD_ID.md +5 -0
  201. package/locales/en.json +680 -30
  202. package/package.json +30 -27
  203. package/dist/es/bootstrap.js +0 -383
  204. package/dist/es/bootstrap.js.map +0 -1
  205. package/dist/es/identity.js +0 -182
  206. package/dist/es/identity.js.map +0 -1
  207. package/dist/es/models/nodeExtensionMethods.js +0 -2
  208. package/dist/es/models/nodeExtensionMethods.js.map +0 -1
  209. package/dist/es/models/nodeFeatures.js +0 -21
  210. package/dist/es/models/nodeFeatures.js.map +0 -1
  211. package/dist/es/server.js +0 -81
  212. package/dist/es/server.js.map +0 -1
  213. package/dist/types/bootstrap.d.ts +0 -68
  214. package/dist/types/identity.d.ts +0 -14
  215. package/dist/types/models/nodeExtensionMethods.d.ts +0 -27
  216. package/dist/types/models/nodeFeatures.d.ts +0 -21
  217. package/docs/detailed-guide.md +0 -129
  218. package/docs/reference/functions/bootstrap.md +0 -29
  219. package/docs/reference/functions/bootstrapAuth.md +0 -35
  220. package/docs/reference/functions/bootstrapBlobEncryption.md +0 -35
  221. package/docs/reference/functions/bootstrapImmutableProofMethod.md +0 -35
  222. package/docs/reference/functions/bootstrapNodeAdminUser.md +0 -35
  223. package/docs/reference/functions/bootstrapNodeId.md +0 -35
  224. package/docs/reference/functions/bootstrapSynchronisedStorage.md +0 -35
  225. package/docs/reference/functions/bootstrapTenantId.md +0 -35
  226. package/docs/reference/functions/getFeatures.md +0 -19
  227. package/docs/reference/type-aliases/NodeFeatures.md +0 -5
  228. package/docs/reference/variables/NodeFeatures.md +0 -25
  229. package/docs/reference/variables/SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID.md +0 -3
  230. package/docs/reference/variables/VC_AUTHENTICATION_VERIFICATION_METHOD_ID.md +0 -3
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@twin.org/node-core",
3
- "version": "0.0.3-next.9",
3
+ "version": "0.9.0",
4
4
  "description": "TWIN Node Core for serving APIs using the specified configuration",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "git+https://github.com/twinfoundation/node.git",
7
+ "url": "git+https://github.com/iotaledger/twin-node.git",
8
8
  "directory": "packages/node-core"
9
9
  },
10
10
  "author": "martyn.janes@iota.org",
@@ -14,30 +14,33 @@
14
14
  "node": ">=20.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/api-auth-entity-storage-service": "next",
18
- "@twin.org/api-tenant-processor": "next",
19
- "@twin.org/cli-core": "next",
20
- "@twin.org/context": "next",
21
- "@twin.org/core": "next",
22
- "@twin.org/crypto": "next",
23
- "@twin.org/data-space-connector-models": "next",
24
- "@twin.org/engine": "next",
25
- "@twin.org/engine-core": "next",
26
- "@twin.org/engine-models": "next",
27
- "@twin.org/engine-server": "next",
28
- "@twin.org/engine-server-types": "next",
29
- "@twin.org/engine-types": "next",
30
- "@twin.org/entity": "next",
31
- "@twin.org/entity-storage-models": "next",
32
- "@twin.org/identity-models": "next",
33
- "@twin.org/modules": "next",
34
- "@twin.org/rights-management-rest-client": "next",
35
- "@twin.org/standards-w3c-odrl": "next",
36
- "@twin.org/trust-models": "next",
37
- "@twin.org/vault-models": "next",
38
- "@twin.org/wallet-models": "next",
39
- "dotenv": "17.2.3",
40
- "schema-dts": "1.1.5"
17
+ "@twin.org/api-auth-entity-storage-service": "^0.9.0",
18
+ "@twin.org/api-tenant-processor": "^0.9.0",
19
+ "@twin.org/cli-core": "^0.9.0",
20
+ "@twin.org/context": "^0.9.0",
21
+ "@twin.org/core": "^0.9.0",
22
+ "@twin.org/crypto": "^0.9.0",
23
+ "@twin.org/dataspace-models": "^0.9.0",
24
+ "@twin.org/engine": "^0.9.0",
25
+ "@twin.org/engine-core": "^0.9.0",
26
+ "@twin.org/engine-models": "^0.9.0",
27
+ "@twin.org/engine-server": "^0.9.0",
28
+ "@twin.org/engine-server-types": "^0.9.0",
29
+ "@twin.org/engine-types": "^0.9.0",
30
+ "@twin.org/entity": "^0.9.0",
31
+ "@twin.org/entity-storage-models": "^0.9.0",
32
+ "@twin.org/identity-models": "^0.9.0",
33
+ "@twin.org/modules": "^0.9.0",
34
+ "@twin.org/rights-management-rest-client": "^0.9.0",
35
+ "@twin.org/standards-w3c-did": "^0.9.0",
36
+ "@twin.org/standards-w3c-odrl": "^0.9.0",
37
+ "@twin.org/telemetry-connector-opentelemetry": "^0.9.0",
38
+ "@twin.org/telemetry-models": "^0.9.0",
39
+ "@twin.org/trust-models": "^0.9.0",
40
+ "@twin.org/vault-models": "^0.9.0",
41
+ "@twin.org/wallet-models": "^0.9.0",
42
+ "dotenv": "17.4.2",
43
+ "schema-dts": "2.0.0"
41
44
  },
42
45
  "main": "./dist/es/index.js",
43
46
  "types": "./dist/types/index.d.ts",
@@ -67,7 +70,7 @@
67
70
  "utilities"
68
71
  ],
69
72
  "bugs": {
70
- "url": "git+https://github.com/twinfoundation/node/issues"
73
+ "url": "git+https://github.com/iotaledger/twin-node/issues"
71
74
  },
72
75
  "homepage": "https://twindev.org"
73
76
  }
@@ -1,383 +0,0 @@
1
- // Copyright 2024 IOTA Stiftung.
2
- // SPDX-License-Identifier: Apache-2.0.
3
- import { PasswordHelper } from "@twin.org/api-auth-entity-storage-service";
4
- import { TenantIdHelper } from "@twin.org/api-tenant-processor";
5
- import { ContextIdKeys, ContextIdStore } from "@twin.org/context";
6
- import { Coerce, ComponentFactory, Converter, I18n, Is, RandomHelper } from "@twin.org/core";
7
- import { PasswordGenerator } from "@twin.org/crypto";
8
- import { AuthenticationComponentType } from "@twin.org/engine-server-types";
9
- import { EntityStorageConnectorFactory } from "@twin.org/entity-storage-models";
10
- import { DocumentHelper, IdentityConnectorFactory, IdentityProfileConnectorFactory, IdentityResolverConnectorFactory } from "@twin.org/identity-models";
11
- import { VaultConnectorFactory, VaultKeyType } from "@twin.org/vault-models";
12
- import { ATTESTATION_VERIFICATION_METHOD_ID, AUTH_SIGNING_KEY_ID, BLOB_STORAGE_ENCRYPTION_KEY_ID, IMMUTABLE_PROOF_VERIFICATION_METHOD_ID, SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID, VC_AUTHENTICATION_VERIFICATION_METHOD_ID } from "./defaults.js";
13
- import { createIdentity } from "./identity.js";
14
- import { NodeFeatures } from "./models/nodeFeatures.js";
15
- import { getFeatures } from "./utils.js";
16
- const DEFAULT_NODE_ADMIN_USERNAME = "admin@node";
17
- /**
18
- * Bootstrap the application.
19
- * @param engineCore The engine core for the node.
20
- * @param context The context for the node.
21
- * @param envVars The environment variables for the node.
22
- */
23
- export async function bootstrap(engineCore, context, envVars) {
24
- const features = getFeatures(envVars);
25
- await bootstrapNodeId(engineCore, context, envVars, features);
26
- await ContextIdStore.run(engineCore.getContextIds() ?? {}, async () => {
27
- await bootstrapTenantId(engineCore, context, envVars, features);
28
- await bootstrapNodeAdminUser(engineCore, context, envVars, features);
29
- await bootstrapAuth(engineCore, context, envVars, features);
30
- await bootstrapBlobEncryption(engineCore, context, envVars, features);
31
- const defaultAttestationConnectorType = engineCore.getRegisteredInstanceTypeOptional("attestationConnector");
32
- if (!Is.empty(defaultAttestationConnectorType) &&
33
- Is.stringValue(context.state.nodeOrganizationId)) {
34
- await addVerificationMethod(engineCore, context, context.state.nodeOrganizationId, "attestation", envVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID);
35
- }
36
- const defaultImmutableProofComponentType = engineCore.getRegisteredInstanceTypeOptional("immutableProofComponent");
37
- if (!Is.empty(defaultImmutableProofComponentType) &&
38
- Is.stringValue(context.state.nodeOrganizationId)) {
39
- await addVerificationMethod(engineCore, context, context.state.nodeOrganizationId, "immutable proof", envVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID);
40
- }
41
- if ((Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) &&
42
- Is.stringValue(context.state.nodeId)) {
43
- await addVerificationMethod(engineCore, context, context.state.nodeId, "verifiable credential authentication", envVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID);
44
- }
45
- await bootstrapSynchronisedStorage(engineCore, context, envVars, features);
46
- });
47
- }
48
- /**
49
- * Bootstrap the node creating any necessary resources.
50
- * @param engineCore The engine core for the node.
51
- * @param context The context for the node.
52
- * @param envVars The environment variables for the node.
53
- * @param features The features that are enabled on the node. The features that are enabled on the node.
54
- */
55
- export async function bootstrapNodeId(engineCore, context, envVars, features) {
56
- if (features.includes(NodeFeatures.NodeId)) {
57
- const existingNodeId = envVars.nodeIdentity ?? context.state.nodeId;
58
- const nodeId = await createIdentity(engineCore, envVars, existingNodeId, envVars.nodeMnemonic, existingNodeId, "node", features.includes(NodeFeatures.NodeWallet));
59
- if (nodeId !== context.state.nodeId) {
60
- context.stateDirty = true;
61
- }
62
- context.state.nodeId = nodeId;
63
- engineCore.logInfo(I18n.formatMessage("node.nodeId", {
64
- identity: nodeId
65
- }));
66
- engineCore.addContextId(ContextIdKeys.Node, context.state.nodeId);
67
- }
68
- }
69
- /**
70
- * Bootstrap the node creating any necessary resources.
71
- * @param engineCore The engine core for the node.
72
- * @param context The context for the node.
73
- * @param envVars The environment variables for the node.
74
- * @param features The features that are enabled on the node. The features that are enabled on the node.
75
- */
76
- export async function bootstrapTenantId(engineCore, context, envVars, features) {
77
- // If tenants are enabled we need to add a context id for the node
78
- // so that services such a logging have a default tenant context id
79
- // this will get overwritten by any incoming API requests with the tenant context id
80
- if (Coerce.boolean(envVars.tenantEnabled) ?? false) {
81
- const configuredTenantId = envVars.tenantId ?? context.state.nodeTenantId;
82
- let exists = false;
83
- const tenantAdminServiceComponentType = engineCore.getRegisteredInstanceType("tenantAdminComponent");
84
- const tenantAdminService = ComponentFactory.get(tenantAdminServiceComponentType);
85
- let finalTenantId;
86
- if (Is.stringValue(configuredTenantId)) {
87
- try {
88
- const tenant = await tenantAdminService.get(configuredTenantId);
89
- if (!Is.empty(tenant)) {
90
- engineCore.logInfo(I18n.formatMessage("node.existingTenantId", {
91
- tenantId: configuredTenantId
92
- }));
93
- exists = true;
94
- finalTenantId = configuredTenantId;
95
- }
96
- }
97
- catch { }
98
- }
99
- if (!exists) {
100
- const apiKey = envVars.tenantApiKey ?? TenantIdHelper.generateApiKey();
101
- finalTenantId = configuredTenantId ?? TenantIdHelper.generateTenantId();
102
- await tenantAdminService.set({
103
- id: finalTenantId,
104
- apiKey,
105
- dateCreated: new Date(Date.now()).toISOString(),
106
- label: "node-tenant"
107
- });
108
- engineCore.logInfo(I18n.formatMessage("node.createdTenantId", {
109
- tenantId: finalTenantId,
110
- apiKey
111
- }));
112
- }
113
- if (Is.stringValue(finalTenantId)) {
114
- if (finalTenantId !== context.state.nodeTenantId) {
115
- context.state.nodeTenantId = finalTenantId;
116
- context.stateDirty = true;
117
- }
118
- engineCore.addContextId(ContextIdKeys.Tenant, context.state.nodeTenantId);
119
- }
120
- }
121
- }
122
- /**
123
- * Bootstrap the user.
124
- * @param engineCore The engine core for the node.
125
- * @param context The context for the node.
126
- * @param envVars The environment variables for the node.
127
- * @param features The features that are enabled on the node.
128
- */
129
- export async function bootstrapNodeAdminUser(engineCore, context, envVars, features) {
130
- if (features.includes(NodeFeatures.NodeAdminUser)) {
131
- context.state.nodeOrganizationId =
132
- envVars.organizationIdentity ?? context.state.nodeOrganizationId;
133
- context.state.nodeAdminUserId = envVars.adminUserIdentity ?? context.state.nodeAdminUserId;
134
- const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceType("authenticationComponent");
135
- if (defaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&
136
- Is.stringValue(context.state.nodeId)) {
137
- const authUserEntityStorage = EntityStorageConnectorFactory.get("authentication-user");
138
- const existingOrganizationId = envVars.organizationIdentity ?? context.state.nodeOrganizationId;
139
- const orgId = await createIdentity(engineCore, envVars, existingOrganizationId, envVars.organizationMnemonic, existingOrganizationId, "organization", features.includes(NodeFeatures.NodeWallet));
140
- if (context.state.nodeOrganizationId !== orgId) {
141
- context.state.nodeOrganizationId = orgId;
142
- context.stateDirty = true;
143
- }
144
- const userId = await createIdentity(engineCore, envVars, context.state.nodeAdminUserId, envVars.adminUserMnemonic, context.state.nodeOrganizationId, "user", false);
145
- if (context.state.nodeAdminUserId !== userId) {
146
- context.state.nodeAdminUserId = userId;
147
- context.stateDirty = true;
148
- }
149
- const adminEmail = envVars.adminUserName ?? DEFAULT_NODE_ADMIN_USERNAME;
150
- let nodeAdminUser = await authUserEntityStorage.get(adminEmail);
151
- // If the node admin user doesn't exist, create it
152
- if (Is.empty(nodeAdminUser)) {
153
- engineCore.logInfo(I18n.formatMessage("node.creatingUser", { email: adminEmail }));
154
- const generatedPassword = envVars.adminUserPassword ?? PasswordGenerator.generate(16);
155
- const passwordBytes = Converter.utf8ToBytes(generatedPassword);
156
- const saltBytes = RandomHelper.generate(16);
157
- const hashedPassword = await PasswordHelper.hashPassword(passwordBytes, saltBytes);
158
- nodeAdminUser = {
159
- email: adminEmail,
160
- password: hashedPassword,
161
- salt: Converter.bytesToBase64(saltBytes),
162
- identity: context.state.nodeAdminUserId,
163
- organization: context.state.nodeOrganizationId
164
- };
165
- engineCore.logInfo(I18n.formatMessage("node.nodeAdminUserEmail", { email: adminEmail }));
166
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
167
- const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
168
- const vaultKey = `${context.state.nodeAdminUserId}/admin-password`;
169
- await vaultConnector.setSecret(vaultKey, generatedPassword);
170
- engineCore.logInfo(I18n.formatMessage("node.nodeAdminUserPassword", { vaultKey }));
171
- await authUserEntityStorage.set(nodeAdminUser);
172
- }
173
- else {
174
- engineCore.logInfo(I18n.formatMessage("node.existingUser", { email: adminEmail }));
175
- // The user already exists, so double check the other details match
176
- let needsUpdate = false;
177
- if (nodeAdminUser.identity !== context.state.nodeAdminUserId) {
178
- nodeAdminUser.identity = context.state.nodeAdminUserId;
179
- needsUpdate = true;
180
- }
181
- if (Is.stringValue(envVars.adminUserPassword)) {
182
- const passwordBytes = Converter.utf8ToBytes(envVars.adminUserPassword);
183
- const saltBytes = Converter.base64ToBytes(nodeAdminUser.salt);
184
- const hashedPassword = await PasswordHelper.hashPassword(passwordBytes, saltBytes);
185
- if (nodeAdminUser.password !== hashedPassword) {
186
- nodeAdminUser.password = hashedPassword;
187
- needsUpdate = true;
188
- }
189
- }
190
- if (needsUpdate) {
191
- await authUserEntityStorage.set(nodeAdminUser);
192
- }
193
- }
194
- // We have create a node user, now we need to create a profile for the user
195
- const defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType("identityProfileConnector");
196
- const identityProfileConnector = IdentityProfileConnectorFactory.get(defaultIdentityProfileConnectorType);
197
- if (identityProfileConnector) {
198
- // Add the organization context id when creating the profile
199
- // so that it is partitioned under the organization
200
- const contextIds = (await ContextIdStore.getContextIds()) ?? {};
201
- contextIds[ContextIdKeys.Organization] = context.state.nodeOrganizationId;
202
- await ContextIdStore.run(contextIds, async () => {
203
- let userProfile;
204
- if (Is.stringValue(nodeAdminUser.identity)) {
205
- try {
206
- userProfile = await identityProfileConnector.get(nodeAdminUser.identity);
207
- }
208
- catch { }
209
- }
210
- if (Is.empty(userProfile)) {
211
- engineCore.logInfo(I18n.formatMessage("node.creatingUserProfile", {
212
- identity: nodeAdminUser.identity
213
- }));
214
- const publicProfile = {
215
- "@context": "https://schema.org",
216
- "@type": "Person",
217
- name: "Node Administrator"
218
- };
219
- const privateProfile = {
220
- "@context": "https://schema.org",
221
- "@type": "Person",
222
- givenName: "Node",
223
- familyName: "Administrator",
224
- email: adminEmail
225
- };
226
- await identityProfileConnector.create(nodeAdminUser.identity, publicProfile, privateProfile);
227
- }
228
- else {
229
- engineCore.logInfo(I18n.formatMessage("node.existingUserProfile", {
230
- identity: nodeAdminUser.identity
231
- }));
232
- }
233
- });
234
- }
235
- }
236
- }
237
- }
238
- /**
239
- * Bootstrap the immutable proof verification methods.
240
- * @param engineCore The engine core for the node.
241
- * @param context The context for the node.
242
- * @param envVars The environment variables for the node.
243
- * @param features The features that are enabled on the node.
244
- */
245
- export async function bootstrapImmutableProofMethod(engineCore, context, envVars, features) { }
246
- /**
247
- * Bootstrap the keys for blob encryption.
248
- * @param engineCore The engine core for the node.
249
- * @param context The context for the node.
250
- * @param envVars The environment variables for the node.
251
- * @param features The features that are enabled on the node.
252
- */
253
- export async function bootstrapBlobEncryption(engineCore, context, envVars, features) {
254
- if ((Coerce.boolean(envVars.blobStorageEnableEncryption) ?? false) &&
255
- Is.stringValue(context.state.nodeOrganizationId)) {
256
- // Create a new key for encrypting blobs
257
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
258
- const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
259
- const keyName = `${context.state.nodeOrganizationId}/${envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID}`;
260
- let existingKey;
261
- try {
262
- existingKey = await vaultConnector.getKey(keyName);
263
- }
264
- catch { }
265
- if (Is.empty(existingKey)) {
266
- if (Is.stringBase64(envVars.blobStorageSymmetricEncryptionKey)) {
267
- engineCore.logInfo(I18n.formatMessage("node.addingBlobEncryptionKey", { keyName }));
268
- await vaultConnector.addKey(keyName, VaultKeyType.ChaCha20Poly1305, Converter.base64ToBytes(envVars.blobStorageSymmetricEncryptionKey));
269
- }
270
- else {
271
- engineCore.logInfo(I18n.formatMessage("node.creatingBlobEncryptionKey", { keyName }));
272
- const key = await vaultConnector.createKey(keyName, VaultKeyType.ChaCha20Poly1305);
273
- engineCore.logInfo(I18n.formatMessage("node.createdBlobEncryptionKey", {
274
- keyName,
275
- keyValue: Converter.bytesToBase64(key)
276
- }));
277
- }
278
- }
279
- else {
280
- engineCore.logInfo(I18n.formatMessage("node.existingBlobEncryptionKey", { keyName }));
281
- }
282
- }
283
- }
284
- /**
285
- * Bootstrap the JWT signing key.
286
- * @param engineCore The engine core for the node.
287
- * @param context The context for the node.
288
- * @param envVars The environment variables for the node.
289
- * @param features The features that are enabled on the node.
290
- */
291
- export async function bootstrapAuth(engineCore, context, envVars, features) {
292
- const defaultAuthenticationComponentType = engineCore.getRegisteredInstanceTypeOptional("authenticationComponent");
293
- if (Is.stringValue(defaultAuthenticationComponentType) &&
294
- defaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&
295
- Is.stringValue(context.state.nodeId)) {
296
- // Create a new JWT signing key and a user login for the node
297
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
298
- const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
299
- const keyName = `${context.state.nodeId}/${envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID}`;
300
- let existingKey;
301
- try {
302
- existingKey = await vaultConnector.getKey(keyName);
303
- }
304
- catch { }
305
- if (Is.empty(existingKey)) {
306
- engineCore.logInfo(I18n.formatMessage("node.creatingAuthKey", { keyName }));
307
- await vaultConnector.createKey(keyName, VaultKeyType.Ed25519);
308
- }
309
- else {
310
- engineCore.logInfo(I18n.formatMessage("node.existingAuthKey", { keyName }));
311
- }
312
- }
313
- }
314
- /**
315
- * Bootstrap the synchronised storage blob encryption and verification methods.
316
- * @param engineCore The engine core for the node.
317
- * @param context The context for the node.
318
- * @param envVars The environment variables for the node.
319
- * @param features The features that are enabled on the node.
320
- */
321
- export async function bootstrapSynchronisedStorage(engineCore, context, envVars, features) {
322
- if (Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false) {
323
- // If this is a trusted node we need to add the blob encryption key pair
324
- if (Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {
325
- const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
326
- const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
327
- const keyName = envVars.synchronisedStorageBlobStorageEncryptionKeyId ??
328
- SYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;
329
- let existingKey;
330
- try {
331
- existingKey = await vaultConnector.getKey(keyName);
332
- }
333
- catch { }
334
- if (Is.empty(existingKey)) {
335
- engineCore.logInfo(I18n.formatMessage("node.addingSynchronisedStorageBlobEncryptionKey", { keyName }));
336
- await vaultConnector.addKey(keyName, VaultKeyType.ChaCha20Poly1305, Converter.base64ToBytes(envVars.synchronisedStorageBlobStorageKey));
337
- }
338
- else {
339
- engineCore.logInfo(I18n.formatMessage("node.existingSynchronisedStorageBlobEncryptionKey", { keyName }));
340
- }
341
- }
342
- }
343
- }
344
- /**
345
- * Add a verification method if it doesn't exist.
346
- * @param engineCore The engine core for the node.
347
- * @param context The context for the node.
348
- * @param identity The identity to add the verification method to.
349
- * @param verificationMethodTitle The verification method title.
350
- * @param verificationMethodId The verification method ID.
351
- */
352
- async function addVerificationMethod(engineCore, context, identity, verificationMethodTitle, verificationMethodId) {
353
- if (Is.stringValue(identity) &&
354
- Is.arrayValue(context.config.types.identityConnector) &&
355
- Is.stringValue(verificationMethodId)) {
356
- const defaultIdentityConnectorType = engineCore.getRegisteredInstanceType("identityConnector");
357
- const identityConnector = IdentityConnectorFactory.get(defaultIdentityConnectorType);
358
- const defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType("identityResolverConnector");
359
- const identityResolverConnector = IdentityResolverConnectorFactory.get(defaultIdentityResolverConnectorType);
360
- const identityDocument = await identityResolverConnector.resolveDocument(identity);
361
- const fullMethodId = `${identityDocument.id}#${verificationMethodId}`;
362
- let exists = false;
363
- try {
364
- DocumentHelper.getVerificationMethod(identityDocument, fullMethodId, "assertionMethod");
365
- exists = true;
366
- }
367
- catch { }
368
- if (!exists) {
369
- engineCore.logInfo(I18n.formatMessage("node.addingVerificationMethod", {
370
- title: verificationMethodTitle,
371
- methodId: fullMethodId
372
- }));
373
- await identityConnector.addVerificationMethod(identity, identity, "assertionMethod", verificationMethodId);
374
- }
375
- else {
376
- engineCore.logInfo(I18n.formatMessage("node.existingVerificationMethod", {
377
- title: verificationMethodTitle,
378
- methodId: fullMethodId
379
- }));
380
- }
381
- }
382
- }
383
- //# sourceMappingURL=bootstrap.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,cAAc,EAA2B,MAAM,2CAA2C,CAAC;AACpG,OAAO,EAAE,cAAc,EAA8B,MAAM,gCAAgC,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EACN,2BAA2B,EAE3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,6BAA6B,EAE7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACN,cAAc,EACd,wBAAwB,EACxB,+BAA+B,EAC/B,gCAAgC,EAChC,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,EACN,kCAAkC,EAClC,mBAAmB,EACnB,8BAA8B,EAC9B,sCAAsC,EACtC,mDAAmD,EACnD,wCAAwC,EACxC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,2BAA2B,GAAG,YAAY,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC9B,UAAuB,EACvB,OAAkE,EAClE,OAAkC;IAElC,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAEtC,MAAM,eAAe,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE9D,MAAM,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,iBAAiB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEhE,MAAM,sBAAsB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACrE,MAAM,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5D,MAAM,uBAAuB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEtE,MAAM,+BAA+B,GACpC,UAAU,CAAC,iCAAiC,CAAC,sBAAsB,CAAC,CAAC;QACtE,IACC,CAAC,EAAE,CAAC,KAAK,CAAC,+BAA+B,CAAC;YAC1C,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAC/C,CAAC;YACF,MAAM,qBAAqB,CAC1B,UAAU,EACV,OAAO,EACP,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAChC,aAAa,EACb,OAAO,CAAC,+BAA+B,IAAI,kCAAkC,CAC7E,CAAC;QACH,CAAC;QAED,MAAM,kCAAkC,GACvC,UAAU,CAAC,iCAAiC,CAAC,yBAAyB,CAAC,CAAC;QAEzE,IACC,CAAC,EAAE,CAAC,KAAK,CAAC,kCAAkC,CAAC;YAC7C,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAC/C,CAAC;YACF,MAAM,qBAAqB,CAC1B,UAAU,EACV,OAAO,EACP,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAChC,iBAAiB,EACjB,OAAO,CAAC,kCAAkC,IAAI,sCAAsC,CACpF,CAAC;QACH,CAAC;QAED,IACC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,IAAI,KAAK,CAAC;YAC1D,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EACnC,CAAC;YACF,MAAM,qBAAqB,CAC1B,UAAU,EACV,OAAO,EACP,OAAO,CAAC,KAAK,CAAC,MAAM,EACpB,sCAAsC,EACtC,OAAO,CAAC,oCAAoC,IAAI,wCAAwC,CACxF,CAAC;QACH,CAAC;QAED,MAAM,4BAA4B,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACpC,UAAuB,EACvB,OAAkE,EAClE,OAAkC,EAClC,QAAwB;IAExB,IAAI,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,cAAc,CAClC,UAAU,EACV,OAAO,EACP,cAAc,EACd,OAAO,CAAC,YAAY,EACpB,cAAc,EACd,MAAM,EACN,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAC1C,CAAC;QAEF,IAAI,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACrC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QAE9B,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE;YACjC,QAAQ,EAAE,MAAM;SAChB,CAAC,CACF,CAAC;QAEF,UAAU,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnE,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACtC,UAAuB,EACvB,OAAkE,EAClE,OAAkC,EAClC,QAAwB;IAExB,kEAAkE;IAClE,mEAAmE;IACnE,oFAAoF;IACpF,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,KAAK,EAAE,CAAC;QACpD,MAAM,kBAAkB,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;QAE1E,IAAI,MAAM,GAAG,KAAK,CAAC;QAEnB,MAAM,+BAA+B,GACpC,UAAU,CAAC,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;QAE9D,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,CAC9C,+BAA+B,CAC/B,CAAC;QAEF,IAAI,aAAa,CAAC;QAClB,IAAI,EAAE,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;gBAChE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBACvB,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE;wBAC3C,QAAQ,EAAE,kBAAkB;qBAC5B,CAAC,CACF,CAAC;oBACF,MAAM,GAAG,IAAI,CAAC;oBACd,aAAa,GAAG,kBAAkB,CAAC;gBACpC,CAAC;YACF,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACX,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,IAAI,cAAc,CAAC,cAAc,EAAE,CAAC;YACvE,aAAa,GAAG,kBAAkB,IAAI,cAAc,CAAC,gBAAgB,EAAE,CAAC;YAExE,MAAM,kBAAkB,CAAC,GAAG,CAAC;gBAC5B,EAAE,EAAE,aAAa;gBACjB,MAAM;gBACN,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE;gBAC/C,KAAK,EAAE,aAAa;aACpB,CAAC,CAAC;YAEH,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE;gBAC1C,QAAQ,EAAE,aAAa;gBACvB,MAAM;aACN,CAAC,CACF,CAAC;QACH,CAAC;QAED,IAAI,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;YACnC,IAAI,aAAa,KAAK,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;gBAClD,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,aAAa,CAAC;gBAC3C,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,CAAC;YAED,UAAU,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC3E,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,UAAuB,EACvB,OAAkE,EAClE,OAAkC,EAClC,QAAwB;IAExB,IAAI,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,kBAAkB;YAC/B,OAAO,CAAC,oBAAoB,IAAI,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC;QAE3F,MAAM,kCAAkC,GACvC,UAAU,CAAC,yBAAyB,CAAC,yBAAyB,CAAC,CAAC;QACjE,IACC,kCAAkC,CAAC,UAAU,CAAC,2BAA2B,CAAC,aAAa,CAAC;YACxF,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EACnC,CAAC;YACF,MAAM,qBAAqB,GAC1B,6BAA6B,CAAC,GAAG,uBAEhC,CAAC;YAEH,MAAM,sBAAsB,GAC3B,OAAO,CAAC,oBAAoB,IAAI,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC;YAElE,MAAM,KAAK,GAAG,MAAM,cAAc,CACjC,UAAU,EACV,OAAO,EACP,sBAAsB,EACtB,OAAO,CAAC,oBAAoB,EAC5B,sBAAsB,EACtB,cAAc,EACd,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAC1C,CAAC;YACF,IAAI,OAAO,CAAC,KAAK,CAAC,kBAAkB,KAAK,KAAK,EAAE,CAAC;gBAChD,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,KAAK,CAAC;gBACzC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,cAAc,CAClC,UAAU,EACV,OAAO,EACP,OAAO,CAAC,KAAK,CAAC,eAAe,EAC7B,OAAO,CAAC,iBAAiB,EACzB,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAChC,MAAM,EACN,KAAK,CACL,CAAC;YACF,IAAI,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,MAAM,EAAE,CAAC;gBAC9C,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,MAAM,CAAC;gBACvC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,CAAC;YAED,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,IAAI,2BAA2B,CAAC;YAExE,IAAI,aAAa,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAEhE,kDAAkD;YAClD,IAAI,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC7B,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;gBAEnF,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtF,MAAM,aAAa,GAAG,SAAS,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;gBAC/D,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAC5C,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;gBAEnF,aAAa,GAAG;oBACf,KAAK,EAAE,UAAU;oBACjB,QAAQ,EAAE,cAAc;oBACxB,IAAI,EAAE,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC;oBACxC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,eAAe;oBACvC,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,kBAAkB;iBAC9C,CAAC;gBAEF,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;gBAEzF,MAAM,yBAAyB,GAAG,UAAU,CAAC,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;gBACzF,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;gBAC5E,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,iBAAiB,CAAC;gBACnE,MAAM,cAAc,CAAC,SAAS,CAAS,QAAQ,EAAE,iBAAiB,CAAC,CAAC;gBAEpE,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,4BAA4B,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;gBAEnF,MAAM,qBAAqB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;gBAEnF,mEAAmE;gBACnE,IAAI,WAAW,GAAG,KAAK,CAAC;gBAExB,IAAI,aAAa,CAAC,QAAQ,KAAK,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;oBAC9D,aAAa,CAAC,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC;oBACvD,WAAW,GAAG,IAAI,CAAC;gBACpB,CAAC;gBAED,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBAC/C,MAAM,aAAa,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;oBACvE,MAAM,SAAS,GAAG,SAAS,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;oBAC9D,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;oBAEnF,IAAI,aAAa,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;wBAC/C,aAAa,CAAC,QAAQ,GAAG,cAAc,CAAC;wBACxC,WAAW,GAAG,IAAI,CAAC;oBACpB,CAAC;gBACF,CAAC;gBAED,IAAI,WAAW,EAAE,CAAC;oBACjB,MAAM,qBAAqB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBAChD,CAAC;YACF,CAAC;YAED,2EAA2E;YAC3E,MAAM,mCAAmC,GAAG,UAAU,CAAC,yBAAyB,CAC/E,0BAA0B,CAC1B,CAAC;YACF,MAAM,wBAAwB,GAAG,+BAA+B,CAAC,GAAG,CACnE,mCAAmC,CACnC,CAAC;YAEF,IAAI,wBAAwB,EAAE,CAAC;gBAC9B,4DAA4D;gBAC5D,mDAAmD;gBACnD,MAAM,UAAU,GAAG,CAAC,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC;gBAChE,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC;gBAC1E,MAAM,cAAc,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;oBAC/C,IAAI,WAAW,CAAC;oBAChB,IAAI,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC5C,IAAI,CAAC;4BACJ,WAAW,GAAG,MAAM,wBAAwB,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;wBAC1E,CAAC;wBAAC,MAAM,CAAC,CAAA,CAAC;oBACX,CAAC;oBACD,IAAI,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;wBAC3B,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,0BAA0B,EAAE;4BAC9C,QAAQ,EAAE,aAAa,CAAC,QAAQ;yBAChC,CAAC,CACF,CAAC;wBAEF,MAAM,aAAa,GAAwB;4BAC1C,UAAU,EAAE,oBAAoB;4BAChC,OAAO,EAAE,QAAQ;4BACjB,IAAI,EAAE,oBAAoB;yBAC1B,CAAC;wBACF,MAAM,cAAc,GAAwB;4BAC3C,UAAU,EAAE,oBAAoB;4BAChC,OAAO,EAAE,QAAQ;4BACjB,SAAS,EAAE,MAAM;4BACjB,UAAU,EAAE,eAAe;4BAC3B,KAAK,EAAE,UAAU;yBACjB,CAAC;wBACF,MAAM,wBAAwB,CAAC,MAAM,CACpC,aAAa,CAAC,QAAQ,EACtB,aAAa,EACb,cAAc,CACd,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACP,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,0BAA0B,EAAE;4BAC9C,QAAQ,EAAE,aAAa,CAAC,QAAQ;yBAChC,CAAC,CACF,CAAC;oBACH,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAClD,UAAuB,EACvB,OAAkE,EAClE,OAAkC,EAClC,QAAwB,IACP,CAAC;AAEnB;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,UAAuB,EACvB,OAAkE,EAClE,OAAkC,EAClC,QAAwB;IAExB,IACC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,IAAI,KAAK,CAAC;QAC9D,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAC/C,CAAC;QACF,wCAAwC;QACxC,MAAM,yBAAyB,GAAG,UAAU,CAAC,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;QACzF,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAE5E,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,IAAI,OAAO,CAAC,0BAA0B,IAAI,8BAA8B,EAAE,CAAC;QAE9H,IAAI,WAAW,CAAC;QAEhB,IAAI,CAAC;YACJ,WAAW,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,IAAI,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3B,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,iCAAiC,CAAC,EAAE,CAAC;gBAChE,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,8BAA8B,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;gBACpF,MAAM,cAAc,CAAC,MAAM,CAC1B,OAAO,EACP,YAAY,CAAC,gBAAgB,EAC7B,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAClE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,gCAAgC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;gBACtF,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBACnF,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,+BAA+B,EAAE;oBACnD,OAAO;oBACP,QAAQ,EAAE,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC;iBACtC,CAAC,CACF,CAAC;YACH,CAAC;QACF,CAAC;aAAM,CAAC;YACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,gCAAgC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACvF,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,UAAuB,EACvB,OAAkE,EAClE,OAAkC,EAClC,QAAwB;IAExB,MAAM,kCAAkC,GACvC,UAAU,CAAC,iCAAiC,CAAC,yBAAyB,CAAC,CAAC;IACzE,IACC,EAAE,CAAC,WAAW,CAAC,kCAAkC,CAAC;QAClD,kCAAkC,CAAC,UAAU,CAAC,2BAA2B,CAAC,aAAa,CAAC;QACxF,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EACnC,CAAC;QACF,6DAA6D;QAC7D,MAAM,yBAAyB,GAAG,UAAU,CAAC,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;QACzF,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAE5E,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,gBAAgB,IAAI,mBAAmB,EAAE,CAAC;QAE7F,IAAI,WAAW,CAAC;QAChB,IAAI,CAAC;YACJ,WAAW,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,IAAI,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3B,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5E,MAAM,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CACjD,UAAuB,EACvB,OAAkE,EAClE,OAAkC,EAClC,QAAwB;IAExB,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC,IAAI,KAAK,EAAE,CAAC;QACjE,wEAAwE;QACxE,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,iCAAiC,CAAC,EAAE,CAAC;YAChE,MAAM,yBAAyB,GAAG,UAAU,CAAC,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;YACzF,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YAE5E,MAAM,OAAO,GACZ,OAAO,CAAC,6CAA6C;gBACrD,mDAAmD,CAAC;YACrD,IAAI,WAAW,CAAC;YAEhB,IAAI,CAAC;gBACJ,WAAW,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpD,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAEV,IAAI,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC3B,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,iDAAiD,EAAE,EAAE,OAAO,EAAE,CAAC,CAClF,CAAC;gBACF,MAAM,cAAc,CAAC,MAAM,CAC1B,OAAO,EACP,YAAY,CAAC,gBAAgB,EAC7B,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAClE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,mDAAmD,EAAE,EAAE,OAAO,EAAE,CAAC,CACpF,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,qBAAqB,CACnC,UAAuB,EACvB,OAAkE,EAClE,QAAgB,EAChB,uBAA+B,EAC/B,oBAAwC;IAExC,IACC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC;QACxB,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC;QACrD,EAAE,CAAC,WAAW,CAAC,oBAAoB,CAAC,EACnC,CAAC;QACF,MAAM,4BAA4B,GAAG,UAAU,CAAC,yBAAyB,CAAC,mBAAmB,CAAC,CAAC;QAC/F,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAErF,MAAM,oCAAoC,GAAG,UAAU,CAAC,yBAAyB,CAChF,2BAA2B,CAC3B,CAAC;QACF,MAAM,yBAAyB,GAAG,gCAAgC,CAAC,GAAG,CACrE,oCAAoC,CACpC,CAAC;QAEF,MAAM,gBAAgB,GAAG,MAAM,yBAAyB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAEnF,MAAM,YAAY,GAAG,GAAG,gBAAgB,CAAC,EAAE,IAAI,oBAAoB,EAAE,CAAC;QAEtE,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC;YACJ,cAAc,CAAC,qBAAqB,CAAC,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;YACxF,MAAM,GAAG,IAAI,CAAC;QACf,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,+BAA+B,EAAE;gBACnD,KAAK,EAAE,uBAAuB;gBAC9B,QAAQ,EAAE,YAAY;aACtB,CAAC,CACF,CAAC;YACF,MAAM,iBAAiB,CAAC,qBAAqB,CAC5C,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,oBAAoB,CACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACP,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,iCAAiC,EAAE;gBACrD,KAAK,EAAE,uBAAuB;gBAC9B,QAAQ,EAAE,YAAY;aACtB,CAAC,CACF,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { PasswordHelper, type AuthenticationUser } from \"@twin.org/api-auth-entity-storage-service\";\nimport { TenantIdHelper, type ITenantAdminComponent } from \"@twin.org/api-tenant-processor\";\nimport { ContextIdKeys, ContextIdStore } from \"@twin.org/context\";\nimport { Coerce, ComponentFactory, Converter, I18n, Is, RandomHelper } from \"@twin.org/core\";\nimport { PasswordGenerator } from \"@twin.org/crypto\";\nimport type { IEngineCore, IEngineCoreContext } from \"@twin.org/engine-models\";\nimport {\n\tAuthenticationComponentType,\n\ttype IEngineServerConfig\n} from \"@twin.org/engine-server-types\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport {\n\tDocumentHelper,\n\tIdentityConnectorFactory,\n\tIdentityProfileConnectorFactory,\n\tIdentityResolverConnectorFactory\n} from \"@twin.org/identity-models\";\nimport { nameofKebabCase } from \"@twin.org/nameof\";\nimport { VaultConnectorFactory, VaultKeyType } from \"@twin.org/vault-models\";\nimport type { Person, WithContext } from \"schema-dts\";\nimport {\n\tATTESTATION_VERIFICATION_METHOD_ID,\n\tAUTH_SIGNING_KEY_ID,\n\tBLOB_STORAGE_ENCRYPTION_KEY_ID,\n\tIMMUTABLE_PROOF_VERIFICATION_METHOD_ID,\n\tSYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID,\n\tVC_AUTHENTICATION_VERIFICATION_METHOD_ID\n} from \"./defaults.js\";\nimport { createIdentity } from \"./identity.js\";\nimport type { INodeEngineState } from \"./models/INodeEngineState.js\";\nimport type { INodeEnvironmentVariables } from \"./models/INodeEnvironmentVariables.js\";\nimport { NodeFeatures } from \"./models/nodeFeatures.js\";\nimport { getFeatures } from \"./utils.js\";\n\nconst DEFAULT_NODE_ADMIN_USERNAME = \"admin@node\";\n\n/**\n * Bootstrap the application.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n */\nexport async function bootstrap(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables\n): Promise<void> {\n\tconst features = getFeatures(envVars);\n\n\tawait bootstrapNodeId(engineCore, context, envVars, features);\n\n\tawait ContextIdStore.run(engineCore.getContextIds() ?? {}, async () => {\n\t\tawait bootstrapTenantId(engineCore, context, envVars, features);\n\n\t\tawait bootstrapNodeAdminUser(engineCore, context, envVars, features);\n\t\tawait bootstrapAuth(engineCore, context, envVars, features);\n\t\tawait bootstrapBlobEncryption(engineCore, context, envVars, features);\n\n\t\tconst defaultAttestationConnectorType =\n\t\t\tengineCore.getRegisteredInstanceTypeOptional(\"attestationConnector\");\n\t\tif (\n\t\t\t!Is.empty(defaultAttestationConnectorType) &&\n\t\t\tIs.stringValue(context.state.nodeOrganizationId)\n\t\t) {\n\t\t\tawait addVerificationMethod(\n\t\t\t\tengineCore,\n\t\t\t\tcontext,\n\t\t\t\tcontext.state.nodeOrganizationId,\n\t\t\t\t\"attestation\",\n\t\t\t\tenvVars.attestationVerificationMethodId ?? ATTESTATION_VERIFICATION_METHOD_ID\n\t\t\t);\n\t\t}\n\n\t\tconst defaultImmutableProofComponentType =\n\t\t\tengineCore.getRegisteredInstanceTypeOptional(\"immutableProofComponent\");\n\n\t\tif (\n\t\t\t!Is.empty(defaultImmutableProofComponentType) &&\n\t\t\tIs.stringValue(context.state.nodeOrganizationId)\n\t\t) {\n\t\t\tawait addVerificationMethod(\n\t\t\t\tengineCore,\n\t\t\t\tcontext,\n\t\t\t\tcontext.state.nodeOrganizationId,\n\t\t\t\t\"immutable proof\",\n\t\t\t\tenvVars.immutableProofVerificationMethodId ?? IMMUTABLE_PROOF_VERIFICATION_METHOD_ID\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\t(Coerce.boolean(envVars.vcAuthenticationEnabled) ?? false) &&\n\t\t\tIs.stringValue(context.state.nodeId)\n\t\t) {\n\t\t\tawait addVerificationMethod(\n\t\t\t\tengineCore,\n\t\t\t\tcontext,\n\t\t\t\tcontext.state.nodeId,\n\t\t\t\t\"verifiable credential authentication\",\n\t\t\t\tenvVars.vcAuthenticationVerificationMethodId ?? VC_AUTHENTICATION_VERIFICATION_METHOD_ID\n\t\t\t);\n\t\t}\n\n\t\tawait bootstrapSynchronisedStorage(engineCore, context, envVars, features);\n\t});\n}\n\n/**\n * Bootstrap the node creating any necessary resources.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n * @param features The features that are enabled on the node. The features that are enabled on the node.\n */\nexport async function bootstrapNodeId(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tfeatures: NodeFeatures[]\n): Promise<void> {\n\tif (features.includes(NodeFeatures.NodeId)) {\n\t\tconst existingNodeId = envVars.nodeIdentity ?? context.state.nodeId;\n\n\t\tconst nodeId = await createIdentity(\n\t\t\tengineCore,\n\t\t\tenvVars,\n\t\t\texistingNodeId,\n\t\t\tenvVars.nodeMnemonic,\n\t\t\texistingNodeId,\n\t\t\t\"node\",\n\t\t\tfeatures.includes(NodeFeatures.NodeWallet)\n\t\t);\n\n\t\tif (nodeId !== context.state.nodeId) {\n\t\t\tcontext.stateDirty = true;\n\t\t}\n\t\tcontext.state.nodeId = nodeId;\n\n\t\tengineCore.logInfo(\n\t\t\tI18n.formatMessage(\"node.nodeId\", {\n\t\t\t\tidentity: nodeId\n\t\t\t})\n\t\t);\n\n\t\tengineCore.addContextId(ContextIdKeys.Node, context.state.nodeId);\n\t}\n}\n\n/**\n * Bootstrap the node creating any necessary resources.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n * @param features The features that are enabled on the node. The features that are enabled on the node.\n */\nexport async function bootstrapTenantId(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tfeatures: NodeFeatures[]\n): Promise<void> {\n\t// If tenants are enabled we need to add a context id for the node\n\t// so that services such a logging have a default tenant context id\n\t// this will get overwritten by any incoming API requests with the tenant context id\n\tif (Coerce.boolean(envVars.tenantEnabled) ?? false) {\n\t\tconst configuredTenantId = envVars.tenantId ?? context.state.nodeTenantId;\n\n\t\tlet exists = false;\n\n\t\tconst tenantAdminServiceComponentType =\n\t\t\tengineCore.getRegisteredInstanceType(\"tenantAdminComponent\");\n\n\t\tconst tenantAdminService = ComponentFactory.get<ITenantAdminComponent>(\n\t\t\ttenantAdminServiceComponentType\n\t\t);\n\n\t\tlet finalTenantId;\n\t\tif (Is.stringValue(configuredTenantId)) {\n\t\t\ttry {\n\t\t\t\tconst tenant = await tenantAdminService.get(configuredTenantId);\n\t\t\t\tif (!Is.empty(tenant)) {\n\t\t\t\t\tengineCore.logInfo(\n\t\t\t\t\t\tI18n.formatMessage(\"node.existingTenantId\", {\n\t\t\t\t\t\t\ttenantId: configuredTenantId\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\texists = true;\n\t\t\t\t\tfinalTenantId = configuredTenantId;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\n\t\tif (!exists) {\n\t\t\tconst apiKey = envVars.tenantApiKey ?? TenantIdHelper.generateApiKey();\n\t\t\tfinalTenantId = configuredTenantId ?? TenantIdHelper.generateTenantId();\n\n\t\t\tawait tenantAdminService.set({\n\t\t\t\tid: finalTenantId,\n\t\t\t\tapiKey,\n\t\t\t\tdateCreated: new Date(Date.now()).toISOString(),\n\t\t\t\tlabel: \"node-tenant\"\n\t\t\t});\n\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.createdTenantId\", {\n\t\t\t\t\ttenantId: finalTenantId,\n\t\t\t\t\tapiKey\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\n\t\tif (Is.stringValue(finalTenantId)) {\n\t\t\tif (finalTenantId !== context.state.nodeTenantId) {\n\t\t\t\tcontext.state.nodeTenantId = finalTenantId;\n\t\t\t\tcontext.stateDirty = true;\n\t\t\t}\n\n\t\t\tengineCore.addContextId(ContextIdKeys.Tenant, context.state.nodeTenantId);\n\t\t}\n\t}\n}\n\n/**\n * Bootstrap the user.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n * @param features The features that are enabled on the node.\n */\nexport async function bootstrapNodeAdminUser(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tfeatures: NodeFeatures[]\n): Promise<void> {\n\tif (features.includes(NodeFeatures.NodeAdminUser)) {\n\t\tcontext.state.nodeOrganizationId =\n\t\t\tenvVars.organizationIdentity ?? context.state.nodeOrganizationId;\n\t\tcontext.state.nodeAdminUserId = envVars.adminUserIdentity ?? context.state.nodeAdminUserId;\n\n\t\tconst defaultAuthenticationComponentType =\n\t\t\tengineCore.getRegisteredInstanceType(\"authenticationComponent\");\n\t\tif (\n\t\t\tdefaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&\n\t\t\tIs.stringValue(context.state.nodeId)\n\t\t) {\n\t\t\tconst authUserEntityStorage =\n\t\t\t\tEntityStorageConnectorFactory.get<IEntityStorageConnector<AuthenticationUser>>(\n\t\t\t\t\tnameofKebabCase<AuthenticationUser>()\n\t\t\t\t);\n\n\t\t\tconst existingOrganizationId =\n\t\t\t\tenvVars.organizationIdentity ?? context.state.nodeOrganizationId;\n\n\t\t\tconst orgId = await createIdentity(\n\t\t\t\tengineCore,\n\t\t\t\tenvVars,\n\t\t\t\texistingOrganizationId,\n\t\t\t\tenvVars.organizationMnemonic,\n\t\t\t\texistingOrganizationId,\n\t\t\t\t\"organization\",\n\t\t\t\tfeatures.includes(NodeFeatures.NodeWallet)\n\t\t\t);\n\t\t\tif (context.state.nodeOrganizationId !== orgId) {\n\t\t\t\tcontext.state.nodeOrganizationId = orgId;\n\t\t\t\tcontext.stateDirty = true;\n\t\t\t}\n\n\t\t\tconst userId = await createIdentity(\n\t\t\t\tengineCore,\n\t\t\t\tenvVars,\n\t\t\t\tcontext.state.nodeAdminUserId,\n\t\t\t\tenvVars.adminUserMnemonic,\n\t\t\t\tcontext.state.nodeOrganizationId,\n\t\t\t\t\"user\",\n\t\t\t\tfalse\n\t\t\t);\n\t\t\tif (context.state.nodeAdminUserId !== userId) {\n\t\t\t\tcontext.state.nodeAdminUserId = userId;\n\t\t\t\tcontext.stateDirty = true;\n\t\t\t}\n\n\t\t\tconst adminEmail = envVars.adminUserName ?? DEFAULT_NODE_ADMIN_USERNAME;\n\n\t\t\tlet nodeAdminUser = await authUserEntityStorage.get(adminEmail);\n\n\t\t\t// If the node admin user doesn't exist, create it\n\t\t\tif (Is.empty(nodeAdminUser)) {\n\t\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.creatingUser\", { email: adminEmail }));\n\n\t\t\t\tconst generatedPassword = envVars.adminUserPassword ?? PasswordGenerator.generate(16);\n\t\t\t\tconst passwordBytes = Converter.utf8ToBytes(generatedPassword);\n\t\t\t\tconst saltBytes = RandomHelper.generate(16);\n\t\t\t\tconst hashedPassword = await PasswordHelper.hashPassword(passwordBytes, saltBytes);\n\n\t\t\t\tnodeAdminUser = {\n\t\t\t\t\temail: adminEmail,\n\t\t\t\t\tpassword: hashedPassword,\n\t\t\t\t\tsalt: Converter.bytesToBase64(saltBytes),\n\t\t\t\t\tidentity: context.state.nodeAdminUserId,\n\t\t\t\t\torganization: context.state.nodeOrganizationId\n\t\t\t\t};\n\n\t\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.nodeAdminUserEmail\", { email: adminEmail }));\n\n\t\t\t\tconst defaultVaultConnectorType = engineCore.getRegisteredInstanceType(\"vaultConnector\");\n\t\t\t\tconst vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);\n\t\t\t\tconst vaultKey = `${context.state.nodeAdminUserId}/admin-password`;\n\t\t\t\tawait vaultConnector.setSecret<string>(vaultKey, generatedPassword);\n\n\t\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.nodeAdminUserPassword\", { vaultKey }));\n\n\t\t\t\tawait authUserEntityStorage.set(nodeAdminUser);\n\t\t\t} else {\n\t\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.existingUser\", { email: adminEmail }));\n\n\t\t\t\t// The user already exists, so double check the other details match\n\t\t\t\tlet needsUpdate = false;\n\n\t\t\t\tif (nodeAdminUser.identity !== context.state.nodeAdminUserId) {\n\t\t\t\t\tnodeAdminUser.identity = context.state.nodeAdminUserId;\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t}\n\n\t\t\t\tif (Is.stringValue(envVars.adminUserPassword)) {\n\t\t\t\t\tconst passwordBytes = Converter.utf8ToBytes(envVars.adminUserPassword);\n\t\t\t\t\tconst saltBytes = Converter.base64ToBytes(nodeAdminUser.salt);\n\t\t\t\t\tconst hashedPassword = await PasswordHelper.hashPassword(passwordBytes, saltBytes);\n\n\t\t\t\t\tif (nodeAdminUser.password !== hashedPassword) {\n\t\t\t\t\t\tnodeAdminUser.password = hashedPassword;\n\t\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (needsUpdate) {\n\t\t\t\t\tawait authUserEntityStorage.set(nodeAdminUser);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We have create a node user, now we need to create a profile for the user\n\t\t\tconst defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType(\n\t\t\t\t\"identityProfileConnector\"\n\t\t\t);\n\t\t\tconst identityProfileConnector = IdentityProfileConnectorFactory.get(\n\t\t\t\tdefaultIdentityProfileConnectorType\n\t\t\t);\n\n\t\t\tif (identityProfileConnector) {\n\t\t\t\t// Add the organization context id when creating the profile\n\t\t\t\t// so that it is partitioned under the organization\n\t\t\t\tconst contextIds = (await ContextIdStore.getContextIds()) ?? {};\n\t\t\t\tcontextIds[ContextIdKeys.Organization] = context.state.nodeOrganizationId;\n\t\t\t\tawait ContextIdStore.run(contextIds, async () => {\n\t\t\t\t\tlet userProfile;\n\t\t\t\t\tif (Is.stringValue(nodeAdminUser.identity)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tuserProfile = await identityProfileConnector.get(nodeAdminUser.identity);\n\t\t\t\t\t\t} catch {}\n\t\t\t\t\t}\n\t\t\t\t\tif (Is.empty(userProfile)) {\n\t\t\t\t\t\tengineCore.logInfo(\n\t\t\t\t\t\t\tI18n.formatMessage(\"node.creatingUserProfile\", {\n\t\t\t\t\t\t\t\tidentity: nodeAdminUser.identity\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst publicProfile: WithContext<Person> = {\n\t\t\t\t\t\t\t\"@context\": \"https://schema.org\",\n\t\t\t\t\t\t\t\"@type\": \"Person\",\n\t\t\t\t\t\t\tname: \"Node Administrator\"\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst privateProfile: WithContext<Person> = {\n\t\t\t\t\t\t\t\"@context\": \"https://schema.org\",\n\t\t\t\t\t\t\t\"@type\": \"Person\",\n\t\t\t\t\t\t\tgivenName: \"Node\",\n\t\t\t\t\t\t\tfamilyName: \"Administrator\",\n\t\t\t\t\t\t\temail: adminEmail\n\t\t\t\t\t\t};\n\t\t\t\t\t\tawait identityProfileConnector.create(\n\t\t\t\t\t\t\tnodeAdminUser.identity,\n\t\t\t\t\t\t\tpublicProfile,\n\t\t\t\t\t\t\tprivateProfile\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tengineCore.logInfo(\n\t\t\t\t\t\t\tI18n.formatMessage(\"node.existingUserProfile\", {\n\t\t\t\t\t\t\t\tidentity: nodeAdminUser.identity\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Bootstrap the immutable proof verification methods.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n * @param features The features that are enabled on the node.\n */\nexport async function bootstrapImmutableProofMethod(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tfeatures: NodeFeatures[]\n): Promise<void> {}\n\n/**\n * Bootstrap the keys for blob encryption.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n * @param features The features that are enabled on the node.\n */\nexport async function bootstrapBlobEncryption(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tfeatures: NodeFeatures[]\n): Promise<void> {\n\tif (\n\t\t(Coerce.boolean(envVars.blobStorageEnableEncryption) ?? false) &&\n\t\tIs.stringValue(context.state.nodeOrganizationId)\n\t) {\n\t\t// Create a new key for encrypting blobs\n\t\tconst defaultVaultConnectorType = engineCore.getRegisteredInstanceType(\"vaultConnector\");\n\t\tconst vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);\n\n\t\tconst keyName = `${context.state.nodeOrganizationId}/${envVars.blobStorageEncryptionKeyId ?? BLOB_STORAGE_ENCRYPTION_KEY_ID}`;\n\n\t\tlet existingKey;\n\n\t\ttry {\n\t\t\texistingKey = await vaultConnector.getKey(keyName);\n\t\t} catch {}\n\n\t\tif (Is.empty(existingKey)) {\n\t\t\tif (Is.stringBase64(envVars.blobStorageSymmetricEncryptionKey)) {\n\t\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.addingBlobEncryptionKey\", { keyName }));\n\t\t\t\tawait vaultConnector.addKey(\n\t\t\t\t\tkeyName,\n\t\t\t\t\tVaultKeyType.ChaCha20Poly1305,\n\t\t\t\t\tConverter.base64ToBytes(envVars.blobStorageSymmetricEncryptionKey)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.creatingBlobEncryptionKey\", { keyName }));\n\t\t\t\tconst key = await vaultConnector.createKey(keyName, VaultKeyType.ChaCha20Poly1305);\n\t\t\t\tengineCore.logInfo(\n\t\t\t\t\tI18n.formatMessage(\"node.createdBlobEncryptionKey\", {\n\t\t\t\t\t\tkeyName,\n\t\t\t\t\t\tkeyValue: Converter.bytesToBase64(key)\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.existingBlobEncryptionKey\", { keyName }));\n\t\t}\n\t}\n}\n\n/**\n * Bootstrap the JWT signing key.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n * @param features The features that are enabled on the node.\n */\nexport async function bootstrapAuth(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tfeatures: NodeFeatures[]\n): Promise<void> {\n\tconst defaultAuthenticationComponentType =\n\t\tengineCore.getRegisteredInstanceTypeOptional(\"authenticationComponent\");\n\tif (\n\t\tIs.stringValue(defaultAuthenticationComponentType) &&\n\t\tdefaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&\n\t\tIs.stringValue(context.state.nodeId)\n\t) {\n\t\t// Create a new JWT signing key and a user login for the node\n\t\tconst defaultVaultConnectorType = engineCore.getRegisteredInstanceType(\"vaultConnector\");\n\t\tconst vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);\n\n\t\tconst keyName = `${context.state.nodeId}/${envVars.authSigningKeyId ?? AUTH_SIGNING_KEY_ID}`;\n\n\t\tlet existingKey;\n\t\ttry {\n\t\t\texistingKey = await vaultConnector.getKey(keyName);\n\t\t} catch {}\n\n\t\tif (Is.empty(existingKey)) {\n\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.creatingAuthKey\", { keyName }));\n\t\t\tawait vaultConnector.createKey(keyName, VaultKeyType.Ed25519);\n\t\t} else {\n\t\t\tengineCore.logInfo(I18n.formatMessage(\"node.existingAuthKey\", { keyName }));\n\t\t}\n\t}\n}\n\n/**\n * Bootstrap the synchronised storage blob encryption and verification methods.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param envVars The environment variables for the node.\n * @param features The features that are enabled on the node.\n */\nexport async function bootstrapSynchronisedStorage(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tfeatures: NodeFeatures[]\n): Promise<void> {\n\tif (Coerce.boolean(envVars.synchronisedStorageEnabled) ?? false) {\n\t\t// If this is a trusted node we need to add the blob encryption key pair\n\t\tif (Is.stringBase64(envVars.synchronisedStorageBlobStorageKey)) {\n\t\t\tconst defaultVaultConnectorType = engineCore.getRegisteredInstanceType(\"vaultConnector\");\n\t\t\tconst vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);\n\n\t\t\tconst keyName =\n\t\t\t\tenvVars.synchronisedStorageBlobStorageEncryptionKeyId ??\n\t\t\t\tSYNCHRONISED_STORAGE_BLOB_STORAGE_ENCRYPTION_KEY_ID;\n\t\t\tlet existingKey;\n\n\t\t\ttry {\n\t\t\t\texistingKey = await vaultConnector.getKey(keyName);\n\t\t\t} catch {}\n\n\t\t\tif (Is.empty(existingKey)) {\n\t\t\t\tengineCore.logInfo(\n\t\t\t\t\tI18n.formatMessage(\"node.addingSynchronisedStorageBlobEncryptionKey\", { keyName })\n\t\t\t\t);\n\t\t\t\tawait vaultConnector.addKey(\n\t\t\t\t\tkeyName,\n\t\t\t\t\tVaultKeyType.ChaCha20Poly1305,\n\t\t\t\t\tConverter.base64ToBytes(envVars.synchronisedStorageBlobStorageKey)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tengineCore.logInfo(\n\t\t\t\t\tI18n.formatMessage(\"node.existingSynchronisedStorageBlobEncryptionKey\", { keyName })\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Add a verification method if it doesn't exist.\n * @param engineCore The engine core for the node.\n * @param context The context for the node.\n * @param identity The identity to add the verification method to.\n * @param verificationMethodTitle The verification method title.\n * @param verificationMethodId The verification method ID.\n */\nasync function addVerificationMethod(\n\tengineCore: IEngineCore,\n\tcontext: IEngineCoreContext<IEngineServerConfig, INodeEngineState>,\n\tidentity: string,\n\tverificationMethodTitle: string,\n\tverificationMethodId: string | undefined\n): Promise<void> {\n\tif (\n\t\tIs.stringValue(identity) &&\n\t\tIs.arrayValue(context.config.types.identityConnector) &&\n\t\tIs.stringValue(verificationMethodId)\n\t) {\n\t\tconst defaultIdentityConnectorType = engineCore.getRegisteredInstanceType(\"identityConnector\");\n\t\tconst identityConnector = IdentityConnectorFactory.get(defaultIdentityConnectorType);\n\n\t\tconst defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType(\n\t\t\t\"identityResolverConnector\"\n\t\t);\n\t\tconst identityResolverConnector = IdentityResolverConnectorFactory.get(\n\t\t\tdefaultIdentityResolverConnectorType\n\t\t);\n\n\t\tconst identityDocument = await identityResolverConnector.resolveDocument(identity);\n\n\t\tconst fullMethodId = `${identityDocument.id}#${verificationMethodId}`;\n\n\t\tlet exists = false;\n\t\ttry {\n\t\t\tDocumentHelper.getVerificationMethod(identityDocument, fullMethodId, \"assertionMethod\");\n\t\t\texists = true;\n\t\t} catch {}\n\n\t\tif (!exists) {\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.addingVerificationMethod\", {\n\t\t\t\t\ttitle: verificationMethodTitle,\n\t\t\t\t\tmethodId: fullMethodId\n\t\t\t\t})\n\t\t\t);\n\t\t\tawait identityConnector.addVerificationMethod(\n\t\t\t\tidentity,\n\t\t\t\tidentity,\n\t\t\t\t\"assertionMethod\",\n\t\t\t\tverificationMethodId\n\t\t\t);\n\t\t} else {\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.existingVerificationMethod\", {\n\t\t\t\t\ttitle: verificationMethodTitle,\n\t\t\t\t\tmethodId: fullMethodId\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}\n}\n"]}