@twin.org/node-core 0.0.3-next.3 → 0.0.3-next.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/README.md +3 -1
  2. package/dist/es/builders/engineEnvBuilder.js +194 -123
  3. package/dist/es/builders/engineEnvBuilder.js.map +1 -1
  4. package/dist/es/builders/engineServerEnvBuilder.js +63 -24
  5. package/dist/es/builders/engineServerEnvBuilder.js.map +1 -1
  6. package/dist/es/cli.js +247 -0
  7. package/dist/es/cli.js.map +1 -0
  8. package/dist/es/commands/bootstrapLegacy.js +186 -0
  9. package/dist/es/commands/bootstrapLegacy.js.map +1 -0
  10. package/dist/es/commands/help.js +85 -0
  11. package/dist/es/commands/help.js.map +1 -0
  12. package/dist/es/commands/identityCreate.js +316 -0
  13. package/dist/es/commands/identityCreate.js.map +1 -0
  14. package/dist/es/commands/identityImports.js +82 -0
  15. package/dist/es/commands/identityImports.js.map +1 -0
  16. package/dist/es/commands/identityVerifiableCredentialCreate.js +146 -0
  17. package/dist/es/commands/identityVerifiableCredentialCreate.js.map +1 -0
  18. package/dist/es/commands/identityVerificationMethodCreate.js +228 -0
  19. package/dist/es/commands/identityVerificationMethodCreate.js.map +1 -0
  20. package/dist/es/commands/identityVerificationMethodImport.js +126 -0
  21. package/dist/es/commands/identityVerificationMethodImport.js.map +1 -0
  22. package/dist/es/commands/nodeSetIdentity.js +64 -0
  23. package/dist/es/commands/nodeSetIdentity.js.map +1 -0
  24. package/dist/es/commands/nodeSetTenant.js +68 -0
  25. package/dist/es/commands/nodeSetTenant.js.map +1 -0
  26. package/dist/es/commands/tenantCreate.js +139 -0
  27. package/dist/es/commands/tenantCreate.js.map +1 -0
  28. package/dist/es/commands/tenantImport.js +97 -0
  29. package/dist/es/commands/tenantImport.js.map +1 -0
  30. package/dist/es/commands/tenantUpdate.js +94 -0
  31. package/dist/es/commands/tenantUpdate.js.map +1 -0
  32. package/dist/es/commands/userCreate.js +212 -0
  33. package/dist/es/commands/userCreate.js.map +1 -0
  34. package/dist/es/commands/userUpdate.js +132 -0
  35. package/dist/es/commands/userUpdate.js.map +1 -0
  36. package/dist/es/commands/vaultKeyCreate.js +191 -0
  37. package/dist/es/commands/vaultKeyCreate.js.map +1 -0
  38. package/dist/es/commands/vaultKeyImport.js +104 -0
  39. package/dist/es/commands/vaultKeyImport.js.map +1 -0
  40. package/dist/es/defaults.js +17 -1
  41. package/dist/es/defaults.js.map +1 -1
  42. package/dist/es/index.js +7 -3
  43. package/dist/es/index.js.map +1 -1
  44. package/dist/es/models/ICliArgs.js +4 -0
  45. package/dist/es/models/ICliArgs.js.map +1 -0
  46. package/dist/es/models/ICliCommand.js +2 -0
  47. package/dist/es/models/ICliCommand.js.map +1 -0
  48. package/dist/es/models/ICliCommandDefinition.js +2 -0
  49. package/dist/es/models/ICliCommandDefinition.js.map +1 -0
  50. package/dist/es/models/ICliCommandDefinitionParam.js +2 -0
  51. package/dist/es/models/ICliCommandDefinitionParam.js.map +1 -0
  52. package/dist/es/models/IEngineEnvironmentVariables.js.map +1 -1
  53. package/dist/es/models/IEngineServerEnvironmentVariables.js.map +1 -1
  54. package/dist/es/models/INodeEngineState.js.map +1 -1
  55. package/dist/es/models/INodeEnvironmentVariables.js.map +1 -1
  56. package/dist/es/models/INodeOptions.js.map +1 -1
  57. package/dist/es/models/cliCommandParamType.js +4 -0
  58. package/dist/es/models/cliCommandParamType.js.map +1 -0
  59. package/dist/es/node.js +84 -39
  60. package/dist/es/node.js.map +1 -1
  61. package/dist/es/start.js +139 -0
  62. package/dist/es/start.js.map +1 -0
  63. package/dist/es/utils.js +12 -22
  64. package/dist/es/utils.js.map +1 -1
  65. package/dist/types/builders/engineEnvBuilder.d.ts +1 -1
  66. package/dist/types/builders/engineServerEnvBuilder.d.ts +4 -2
  67. package/dist/types/cli.d.ts +56 -0
  68. package/dist/types/commands/bootstrapLegacy.d.ts +66 -0
  69. package/dist/types/commands/help.d.ts +23 -0
  70. package/dist/types/commands/identityCreate.d.ts +39 -0
  71. package/dist/types/commands/identityImports.d.ts +24 -0
  72. package/dist/types/commands/identityVerifiableCredentialCreate.d.ts +43 -0
  73. package/dist/types/commands/identityVerificationMethodCreate.d.ts +47 -0
  74. package/dist/types/commands/identityVerificationMethodImport.d.ts +31 -0
  75. package/dist/types/commands/nodeSetIdentity.d.ts +22 -0
  76. package/dist/types/commands/nodeSetTenant.d.ts +22 -0
  77. package/dist/types/commands/tenantCreate.d.ts +38 -0
  78. package/dist/types/commands/tenantImport.d.ts +26 -0
  79. package/dist/types/commands/tenantUpdate.d.ts +26 -0
  80. package/dist/types/commands/userCreate.d.ts +49 -0
  81. package/dist/types/commands/userUpdate.d.ts +38 -0
  82. package/dist/types/commands/vaultKeyCreate.d.ts +43 -0
  83. package/dist/types/commands/vaultKeyImport.d.ts +28 -0
  84. package/dist/types/defaults.d.ts +9 -1
  85. package/dist/types/index.d.ts +7 -3
  86. package/dist/types/models/ICliArgs.d.ts +20 -0
  87. package/dist/types/models/ICliCommand.d.ts +17 -0
  88. package/dist/types/models/ICliCommandDefinition.d.ts +46 -0
  89. package/dist/types/models/ICliCommandDefinitionParam.d.ts +35 -0
  90. package/dist/types/models/IEngineEnvironmentVariables.d.ts +72 -56
  91. package/dist/types/models/IEngineServerEnvironmentVariables.d.ts +4 -0
  92. package/dist/types/models/INodeEngineState.d.ts +0 -8
  93. package/dist/types/models/INodeEnvironmentVariables.d.ts +0 -38
  94. package/dist/types/models/INodeOptions.d.ts +6 -2
  95. package/dist/types/models/cliCommandParamType.d.ts +4 -0
  96. package/dist/types/node.d.ts +5 -4
  97. package/dist/types/{server.d.ts → start.d.ts} +4 -2
  98. package/dist/types/utils.d.ts +6 -8
  99. package/docs/changelog.md +206 -1
  100. package/docs/examples.md +99 -1
  101. package/docs/reference/functions/buildConfiguration.md +1 -1
  102. package/docs/reference/functions/buildEngineServerConfiguration.md +1 -1
  103. package/docs/reference/functions/constructCliCommand.md +27 -0
  104. package/docs/reference/functions/executeCommand.md +29 -0
  105. package/docs/reference/functions/getEnvDefaults.md +19 -0
  106. package/docs/reference/functions/getScriptDirectory.md +19 -0
  107. package/docs/reference/functions/parseCommandLineArgs.md +19 -0
  108. package/docs/reference/functions/processEnvOptions.md +27 -0
  109. package/docs/reference/functions/registerCommands.md +9 -0
  110. package/docs/reference/functions/resolvePackageEntryPoint.md +2 -2
  111. package/docs/reference/functions/run.md +8 -2
  112. package/docs/reference/functions/start.md +9 -3
  113. package/docs/reference/functions/substituteEnvOptions.md +25 -0
  114. package/docs/reference/index.md +14 -12
  115. package/docs/reference/interfaces/ICacheMetadata.md +3 -3
  116. package/docs/reference/interfaces/ICliArgs.md +35 -0
  117. package/docs/reference/interfaces/ICliCommand.md +23 -0
  118. package/docs/reference/interfaces/ICliCommandDefinition.md +101 -0
  119. package/docs/reference/interfaces/ICliCommandDefinitionParam.md +65 -0
  120. package/docs/reference/interfaces/IEngineEnvironmentVariables.md +349 -313
  121. package/docs/reference/interfaces/IEngineServerEnvironmentVariables.md +434 -370
  122. package/docs/reference/interfaces/IModuleProtocol.md +3 -3
  123. package/docs/reference/interfaces/INodeEngineState.md +4 -20
  124. package/docs/reference/interfaces/INodeEnvironmentVariables.md +448 -464
  125. package/docs/reference/interfaces/INodeOptions.md +44 -36
  126. package/docs/reference/interfaces/IProtocolHandlerResult.md +2 -2
  127. package/docs/reference/type-aliases/CliCommandParamType.md +5 -0
  128. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineMethod.md +1 -1
  129. package/docs/reference/type-aliases/NodeExtensionInitialiseEngineServerMethod.md +1 -1
  130. package/docs/reference/type-aliases/NodeExtensionInitialiseMethod.md +1 -1
  131. package/docs/reference/type-aliases/NodeExtensionShutdownMethod.md +1 -1
  132. package/docs/reference/variables/ModuleProtocol.md +5 -5
  133. package/docs/reference/variables/TRUST_VERIFICATION_METHOD_ID.md +3 -0
  134. package/locales/en.json +589 -30
  135. package/package.json +6 -4
  136. package/dist/es/bootstrap.js +0 -360
  137. package/dist/es/bootstrap.js.map +0 -1
  138. package/dist/es/identity.js +0 -169
  139. package/dist/es/identity.js.map +0 -1
  140. package/dist/es/models/nodeFeatures.js +0 -21
  141. package/dist/es/models/nodeFeatures.js.map +0 -1
  142. package/dist/es/server.js +0 -81
  143. package/dist/es/server.js.map +0 -1
  144. package/dist/types/bootstrap.d.ts +0 -68
  145. package/dist/types/identity.d.ts +0 -14
  146. package/dist/types/models/nodeFeatures.d.ts +0 -21
  147. package/docs/detailed-guide.md +0 -129
  148. package/docs/reference/functions/bootstrap.md +0 -29
  149. package/docs/reference/functions/bootstrapAuth.md +0 -35
  150. package/docs/reference/functions/bootstrapBlobEncryption.md +0 -35
  151. package/docs/reference/functions/bootstrapImmutableProofMethod.md +0 -35
  152. package/docs/reference/functions/bootstrapNodeAdminUser.md +0 -35
  153. package/docs/reference/functions/bootstrapNodeId.md +0 -35
  154. package/docs/reference/functions/bootstrapSynchronisedStorage.md +0 -35
  155. package/docs/reference/functions/bootstrapTenantId.md +0 -35
  156. package/docs/reference/functions/getFeatures.md +0 -19
  157. package/docs/reference/type-aliases/NodeFeatures.md +0 -5
  158. package/docs/reference/variables/NodeFeatures.md +0 -25
  159. package/docs/reference/variables/VC_AUTHENTICATION_VERIFICATION_METHOD_ID.md +0 -3
@@ -0,0 +1,212 @@
1
+ import { CLIDisplay, CLIUtils } from "@twin.org/cli-core";
2
+ import { ComponentFactory, GeneralError, Guards, I18n, Is } from "@twin.org/core";
3
+ import { PasswordGenerator } from "@twin.org/crypto";
4
+ import { Did, IdentityProfileConnectorFactory } from "@twin.org/identity-models";
5
+ const COMMAND_NAME = "user-create";
6
+ /**
7
+ * Get the command definition parameters.
8
+ * @param commandDefinitions The registered command definitions.
9
+ */
10
+ export function getCommandDefinitionUserCreate(commandDefinitions) {
11
+ commandDefinitions[COMMAND_NAME] = {
12
+ command: COMMAND_NAME,
13
+ description: I18n.formatMessage("node.cli.commands.user-create.description"),
14
+ example: I18n.formatMessage("node.cli.commands.user-create.example"),
15
+ params: [
16
+ {
17
+ key: "env-prefix",
18
+ type: "string",
19
+ description: I18n.formatMessage("node.cli.commands.user-create.params.env-prefix.description"),
20
+ required: false
21
+ },
22
+ {
23
+ key: "user-identity",
24
+ type: "string",
25
+ extendedType: "DID",
26
+ description: I18n.formatMessage("node.cli.commands.user-create.params.user-identity.description")
27
+ },
28
+ {
29
+ key: "organization-identity",
30
+ type: "string",
31
+ extendedType: "DID",
32
+ description: I18n.formatMessage("node.cli.commands.user-create.params.organization-identity.description")
33
+ },
34
+ {
35
+ key: "email",
36
+ type: "string",
37
+ extendedType: "email",
38
+ description: I18n.formatMessage("node.cli.commands.user-create.params.email.description")
39
+ },
40
+ {
41
+ key: "password",
42
+ type: "string",
43
+ description: I18n.formatMessage("node.cli.commands.user-create.params.password.description"),
44
+ required: false
45
+ },
46
+ {
47
+ key: "scope",
48
+ type: "string",
49
+ description: I18n.formatMessage("node.cli.commands.user-create.params.scope.description"),
50
+ required: false
51
+ },
52
+ {
53
+ key: "given-name",
54
+ type: "string",
55
+ description: I18n.formatMessage("node.cli.commands.user-create.params.given-name.description"),
56
+ required: false
57
+ },
58
+ {
59
+ key: "family-name",
60
+ type: "string",
61
+ description: I18n.formatMessage("node.cli.commands.user-create.params.family-name.description"),
62
+ required: false
63
+ },
64
+ {
65
+ key: "overwrite-mode",
66
+ type: "string",
67
+ description: I18n.formatMessage("node.cli.commands.user-create.params.overwrite-mode.description"),
68
+ options: ["skip", "overwrite", "error"],
69
+ defaultValue: "skip",
70
+ required: false
71
+ },
72
+ {
73
+ key: "load-env",
74
+ type: "string",
75
+ description: I18n.formatMessage("node.cli.commands.user-create.params.load-env.description"),
76
+ required: false
77
+ },
78
+ {
79
+ key: "output-json",
80
+ type: "string",
81
+ description: I18n.formatMessage("node.cli.commands.user-create.params.output-json.description"),
82
+ required: false
83
+ },
84
+ {
85
+ key: "output-env",
86
+ type: "string",
87
+ description: I18n.formatMessage("node.cli.commands.user-create.params.output-env.description"),
88
+ required: false
89
+ },
90
+ {
91
+ key: "output-env-prefix",
92
+ type: "string",
93
+ description: I18n.formatMessage("node.cli.commands.user-create.params.output-env-prefix.description"),
94
+ required: false
95
+ }
96
+ ],
97
+ action: async (engineCore, envVars, params) => userCreate(engineCore, envVars, params)
98
+ };
99
+ }
100
+ /**
101
+ * Command for creating a user.
102
+ * @param engineCore The engine core.
103
+ * @param envVars The environment variables for the node.
104
+ * @param params The parameters for the command.
105
+ * @param params.userIdentity The DID for the user.
106
+ * @param params.organizationIdentity The organization DID for the user.
107
+ * @param params.email The email for the user.
108
+ * @param params.password The password for the user.
109
+ * @param params.scope The scope for the user.
110
+ * @param params.givenName The given name for the user.
111
+ * @param params.familyName The family name for the user.
112
+ * @param params.overwriteMode The mode to use when a user with the same identity already exists.
113
+ * @param params.outputJson The output .json file to store the command output.
114
+ * @param params.outputEnv The output .env file to store the command output.
115
+ * @param params.outputEnvPrefix The prefix to use for variables in the output .env file.
116
+ * @returns The created user details or undefined if skipped.
117
+ */
118
+ export async function userCreate(engineCore, envVars, params) {
119
+ Guards.email("userCreate", "email", params.email);
120
+ Did.guard("userCreate", "user-identity", params.userIdentity);
121
+ Did.guard("userCreate", "organization-identity", params.organizationIdentity);
122
+ if (Is.stringValue(params.password) && params.password.length < 16) {
123
+ throw new GeneralError("userCreate", "passwordTooShort", { minLength: 16 });
124
+ }
125
+ const defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType("identityProfileConnector");
126
+ const identityProfileConnector = IdentityProfileConnectorFactory.get(defaultIdentityProfileConnectorType);
127
+ const defaultAuthenticationAdminComponentType = engineCore.getRegisteredInstanceType("authenticationAdminComponent");
128
+ const authenticationAdminComponent = ComponentFactory.get(defaultAuthenticationAdminComponentType);
129
+ let createUser = true;
130
+ let existingUser;
131
+ try {
132
+ existingUser = await authenticationAdminComponent.get(params.email);
133
+ }
134
+ catch { }
135
+ if (!Is.empty(existingUser)) {
136
+ if (params.overwriteMode === "error") {
137
+ throw new GeneralError("userCreate", "userAlreadyExists");
138
+ }
139
+ else if (params.overwriteMode === "skip") {
140
+ createUser = false;
141
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-create.labels.skipping"));
142
+ }
143
+ else if (params.overwriteMode === "overwrite") {
144
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-create.labels.overwriting"));
145
+ await authenticationAdminComponent.remove(existingUser.email);
146
+ await identityProfileConnector.remove(existingUser.userIdentity);
147
+ }
148
+ }
149
+ let json;
150
+ if (createUser) {
151
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-create.labels.creating"));
152
+ const user = {
153
+ email: params.email,
154
+ password: params.password ?? PasswordGenerator.generate(16),
155
+ userIdentity: params.userIdentity,
156
+ organizationIdentity: params.organizationIdentity,
157
+ scope: params.scope?.split(",").map(s => s.trim()) ?? []
158
+ };
159
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-create.labels.storingUser"));
160
+ if (existingUser) {
161
+ await authenticationAdminComponent.update(user);
162
+ }
163
+ else {
164
+ await authenticationAdminComponent.create(user);
165
+ }
166
+ const name = `${params.givenName ?? ""} ${params.familyName ?? ""}`.trim();
167
+ const publicProfile = {
168
+ "@context": "https://schema.org",
169
+ "@type": "Person",
170
+ name: name.length > 0 ? name : undefined
171
+ };
172
+ const privateProfile = {
173
+ "@context": "https://schema.org",
174
+ "@type": "Person",
175
+ givenName: params.givenName,
176
+ familyName: params.familyName,
177
+ email: params.email
178
+ };
179
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-create.labels.storingProfile"));
180
+ await identityProfileConnector.create(params.userIdentity, publicProfile, privateProfile);
181
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-create.labels.userCreated"));
182
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.user-create.labels.email"), user.email);
183
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.user-create.labels.password"), user.password);
184
+ CLIDisplay.break();
185
+ json = {
186
+ did: params.userIdentity,
187
+ organizationDid: params.organizationIdentity,
188
+ email: params.email,
189
+ password: user.password,
190
+ scope: params.scope?.split(",").map(s => s.trim()) ?? [],
191
+ givenName: params.givenName ?? "",
192
+ familyName: params.familyName ?? ""
193
+ };
194
+ if (Is.stringValue(params.outputJson)) {
195
+ await CLIUtils.writeJsonFile(params.outputJson, json, false);
196
+ }
197
+ if (Is.stringValue(params.outputEnv)) {
198
+ await CLIUtils.writeEnvFile(params.outputEnv, [
199
+ `${params.outputEnvPrefix}DID="${params.userIdentity}"`,
200
+ `${params.outputEnvPrefix}ORGANIZATION_DID="${params.organizationIdentity}"`,
201
+ `${params.outputEnvPrefix}EMAIL="${params.email}"`,
202
+ `${params.outputEnvPrefix}PASSWORD="${user.password}"`,
203
+ `${params.outputEnvPrefix}SCOPE="${params.scope ?? ""}"`,
204
+ `${params.outputEnvPrefix}GIVEN_NAME="${params.givenName ?? ""}"`,
205
+ `${params.outputEnvPrefix}FAMILY_NAME="${params.familyName ?? ""}"`
206
+ ], false);
207
+ }
208
+ }
209
+ CLIDisplay.done();
210
+ return json;
211
+ }
212
+ //# sourceMappingURL=userCreate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userCreate.js","sourceRoot":"","sources":["../../../src/commands/userCreate.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type {\n\tIAuthenticationAdminComponent,\n\tIAuthenticationUser\n} from \"@twin.org/api-auth-entity-storage-models\";\nimport { CLIDisplay, CLIUtils } from \"@twin.org/cli-core\";\nimport { ComponentFactory, GeneralError, Guards, I18n, Is } from \"@twin.org/core\";\nimport { PasswordGenerator } from \"@twin.org/crypto\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport { Did, IdentityProfileConnectorFactory } from \"@twin.org/identity-models\";\nimport type { Person, WithContext } from \"schema-dts\";\nimport type { ICliCommandDefinition } from \"../models/ICliCommandDefinition.js\";\nimport type { INodeEnvironmentVariables } from \"../models/INodeEnvironmentVariables.js\";\n\nconst COMMAND_NAME = \"user-create\";\n\n/**\n * Get the command definition parameters.\n * @param commandDefinitions The registered command definitions.\n */\nexport function getCommandDefinitionUserCreate(commandDefinitions: {\n\t[id: string]: ICliCommandDefinition;\n}): void {\n\tcommandDefinitions[COMMAND_NAME] = {\n\t\tcommand: COMMAND_NAME,\n\t\tdescription: I18n.formatMessage(\"node.cli.commands.user-create.description\"),\n\t\texample: I18n.formatMessage(\"node.cli.commands.user-create.example\"),\n\t\tparams: [\n\t\t\t{\n\t\t\t\tkey: \"env-prefix\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.env-prefix.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"user-identity\",\n\t\t\t\ttype: \"string\",\n\t\t\t\textendedType: \"DID\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.user-identity.description\"\n\t\t\t\t)\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"organization-identity\",\n\t\t\t\ttype: \"string\",\n\t\t\t\textendedType: \"DID\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.organization-identity.description\"\n\t\t\t\t)\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"email\",\n\t\t\t\ttype: \"string\",\n\t\t\t\textendedType: \"email\",\n\t\t\t\tdescription: I18n.formatMessage(\"node.cli.commands.user-create.params.email.description\")\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"password\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.password.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"scope\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\"node.cli.commands.user-create.params.scope.description\"),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"given-name\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.given-name.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"family-name\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.family-name.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"overwrite-mode\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.overwrite-mode.description\"\n\t\t\t\t),\n\t\t\t\toptions: [\"skip\", \"overwrite\", \"error\"],\n\t\t\t\tdefaultValue: \"skip\",\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"load-env\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.load-env.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"output-json\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.output-json.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"output-env\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.output-env.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"output-env-prefix\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-create.params.output-env-prefix.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t}\n\t\t],\n\t\taction: async (engineCore, envVars, params) => userCreate(engineCore, envVars, params)\n\t};\n}\n\n/**\n * Command for creating a user.\n * @param engineCore The engine core.\n * @param envVars The environment variables for the node.\n * @param params The parameters for the command.\n * @param params.userIdentity The DID for the user.\n * @param params.organizationIdentity The organization DID for the user.\n * @param params.email The email for the user.\n * @param params.password The password for the user.\n * @param params.scope The scope for the user.\n * @param params.givenName The given name for the user.\n * @param params.familyName The family name for the user.\n * @param params.overwriteMode The mode to use when a user with the same identity already exists.\n * @param params.outputJson The output .json file to store the command output.\n * @param params.outputEnv The output .env file to store the command output.\n * @param params.outputEnvPrefix The prefix to use for variables in the output .env file.\n * @returns The created user details or undefined if skipped.\n */\nexport async function userCreate(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tparams: {\n\t\tuserIdentity?: string;\n\t\torganizationIdentity?: string;\n\t\temail?: string;\n\t\tpassword?: string;\n\t\tscope?: string;\n\t\tgivenName?: string;\n\t\tfamilyName?: string;\n\t\toverwriteMode?: \"skip\" | \"overwrite\" | \"error\";\n\t\toutputJson?: string;\n\t\toutputEnv?: string;\n\t\toutputEnvPrefix?: string;\n\t}\n): Promise<\n\t| {\n\t\t\tdid: string;\n\t\t\torganizationDid: string;\n\t\t\temail: string;\n\t\t\tpassword: string;\n\t\t\tscope: string[];\n\t\t\tgivenName: string;\n\t\t\tfamilyName: string;\n\t }\n\t| undefined\n> {\n\tGuards.email(\"userCreate\", \"email\", params.email);\n\tDid.guard(\"userCreate\", \"user-identity\", params.userIdentity);\n\tDid.guard(\"userCreate\", \"organization-identity\", params.organizationIdentity);\n\n\tif (Is.stringValue(params.password) && params.password.length < 16) {\n\t\tthrow new GeneralError(\"userCreate\", \"passwordTooShort\", { minLength: 16 });\n\t}\n\n\tconst defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType(\n\t\t\"identityProfileConnector\"\n\t);\n\tconst identityProfileConnector = IdentityProfileConnectorFactory.get(\n\t\tdefaultIdentityProfileConnectorType\n\t);\n\n\tconst defaultAuthenticationAdminComponentType = engineCore.getRegisteredInstanceType(\n\t\t\"authenticationAdminComponent\"\n\t);\n\tconst authenticationAdminComponent = ComponentFactory.get<IAuthenticationAdminComponent>(\n\t\tdefaultAuthenticationAdminComponentType\n\t);\n\n\tlet createUser = true;\n\n\tlet existingUser;\n\ttry {\n\t\texistingUser = await authenticationAdminComponent.get(params.email);\n\t} catch {}\n\n\tif (!Is.empty(existingUser)) {\n\t\tif (params.overwriteMode === \"error\") {\n\t\t\tthrow new GeneralError(\"userCreate\", \"userAlreadyExists\");\n\t\t} else if (params.overwriteMode === \"skip\") {\n\t\t\tcreateUser = false;\n\t\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-create.labels.skipping\"));\n\t\t} else if (params.overwriteMode === \"overwrite\") {\n\t\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-create.labels.overwriting\"));\n\t\t\tawait authenticationAdminComponent.remove(existingUser.email);\n\t\t\tawait identityProfileConnector.remove(existingUser.userIdentity);\n\t\t}\n\t}\n\n\tlet json;\n\tif (createUser) {\n\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-create.labels.creating\"));\n\n\t\tconst user: Omit<IAuthenticationUser, \"salt\"> = {\n\t\t\temail: params.email,\n\t\t\tpassword: params.password ?? PasswordGenerator.generate(16),\n\t\t\tuserIdentity: params.userIdentity,\n\t\t\torganizationIdentity: params.organizationIdentity,\n\t\t\tscope: params.scope?.split(\",\").map(s => s.trim()) ?? []\n\t\t};\n\n\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-create.labels.storingUser\"));\n\n\t\tif (existingUser) {\n\t\t\tawait authenticationAdminComponent.update(user);\n\t\t} else {\n\t\t\tawait authenticationAdminComponent.create(user);\n\t\t}\n\n\t\tconst name = `${params.givenName ?? \"\"} ${params.familyName ?? \"\"}`.trim();\n\t\tconst publicProfile: WithContext<Person> = {\n\t\t\t\"@context\": \"https://schema.org\",\n\t\t\t\"@type\": \"Person\",\n\t\t\tname: name.length > 0 ? name : undefined\n\t\t};\n\t\tconst privateProfile: WithContext<Person> = {\n\t\t\t\"@context\": \"https://schema.org\",\n\t\t\t\"@type\": \"Person\",\n\t\t\tgivenName: params.givenName,\n\t\t\tfamilyName: params.familyName,\n\t\t\temail: params.email\n\t\t};\n\n\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-create.labels.storingProfile\"));\n\t\tawait identityProfileConnector.create(params.userIdentity, publicProfile, privateProfile);\n\n\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-create.labels.userCreated\"));\n\n\t\tCLIDisplay.value(I18n.formatMessage(\"node.cli.commands.user-create.labels.email\"), user.email);\n\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"node.cli.commands.user-create.labels.password\"),\n\t\t\tuser.password\n\t\t);\n\n\t\tCLIDisplay.break();\n\n\t\tjson = {\n\t\t\tdid: params.userIdentity,\n\t\t\torganizationDid: params.organizationIdentity,\n\t\t\temail: params.email,\n\t\t\tpassword: user.password,\n\t\t\tscope: params.scope?.split(\",\").map(s => s.trim()) ?? [],\n\t\t\tgivenName: params.givenName ?? \"\",\n\t\t\tfamilyName: params.familyName ?? \"\"\n\t\t};\n\n\t\tif (Is.stringValue(params.outputJson)) {\n\t\t\tawait CLIUtils.writeJsonFile(params.outputJson, json, false);\n\t\t}\n\n\t\tif (Is.stringValue(params.outputEnv)) {\n\t\t\tawait CLIUtils.writeEnvFile(\n\t\t\t\tparams.outputEnv,\n\t\t\t\t[\n\t\t\t\t\t`${params.outputEnvPrefix}DID=\"${params.userIdentity}\"`,\n\t\t\t\t\t`${params.outputEnvPrefix}ORGANIZATION_DID=\"${params.organizationIdentity}\"`,\n\t\t\t\t\t`${params.outputEnvPrefix}EMAIL=\"${params.email}\"`,\n\t\t\t\t\t`${params.outputEnvPrefix}PASSWORD=\"${user.password}\"`,\n\t\t\t\t\t`${params.outputEnvPrefix}SCOPE=\"${params.scope ?? \"\"}\"`,\n\t\t\t\t\t`${params.outputEnvPrefix}GIVEN_NAME=\"${params.givenName ?? \"\"}\"`,\n\t\t\t\t\t`${params.outputEnvPrefix}FAMILY_NAME=\"${params.familyName ?? \"\"}\"`\n\t\t\t\t],\n\t\t\t\tfalse\n\t\t\t);\n\t\t}\n\t}\n\n\tCLIDisplay.done();\n\n\treturn json;\n}\n"]}
@@ -0,0 +1,132 @@
1
+ import { CLIDisplay } from "@twin.org/cli-core";
2
+ import { ComponentFactory, Guards, I18n, Is } from "@twin.org/core";
3
+ import { Did, IdentityProfileConnectorFactory } from "@twin.org/identity-models";
4
+ const COMMAND_NAME = "user-update";
5
+ /**
6
+ * Get the command definition parameters.
7
+ * @param commandDefinitions The registered command definitions.
8
+ */
9
+ export function getCommandDefinitionUserUpdate(commandDefinitions) {
10
+ commandDefinitions[COMMAND_NAME] = {
11
+ command: COMMAND_NAME,
12
+ description: I18n.formatMessage("node.cli.commands.user-update.description"),
13
+ example: I18n.formatMessage("node.cli.commands.user-update.example"),
14
+ params: [
15
+ {
16
+ key: "env-prefix",
17
+ type: "string",
18
+ description: I18n.formatMessage("node.cli.commands.user-update.params.env-prefix.description"),
19
+ required: false
20
+ },
21
+ {
22
+ key: "user-identity",
23
+ type: "string",
24
+ extendedType: "DID",
25
+ description: I18n.formatMessage("node.cli.commands.user-update.params.user-identity.description"),
26
+ required: false
27
+ },
28
+ {
29
+ key: "organization-identity",
30
+ type: "string",
31
+ extendedType: "DID",
32
+ description: I18n.formatMessage("node.cli.commands.user-update.params.organization-identity.description"),
33
+ required: false
34
+ },
35
+ {
36
+ key: "email",
37
+ type: "string",
38
+ extendedType: "email",
39
+ description: I18n.formatMessage("node.cli.commands.user-update.params.email.description")
40
+ },
41
+ {
42
+ key: "scope",
43
+ type: "string",
44
+ description: I18n.formatMessage("node.cli.commands.user-update.params.scope.description"),
45
+ required: false
46
+ },
47
+ {
48
+ key: "given-name",
49
+ type: "string",
50
+ description: I18n.formatMessage("node.cli.commands.user-update.params.given-name.description"),
51
+ required: false
52
+ },
53
+ {
54
+ key: "family-name",
55
+ type: "string",
56
+ description: I18n.formatMessage("node.cli.commands.user-update.params.family-name.description"),
57
+ required: false
58
+ },
59
+ {
60
+ key: "load-env",
61
+ type: "string",
62
+ description: I18n.formatMessage("node.cli.commands.user-update.params.load-env.description"),
63
+ required: false
64
+ }
65
+ ],
66
+ action: async (engineCore, envVars, params) => userUpdate(engineCore, envVars, params)
67
+ };
68
+ }
69
+ /**
70
+ * Command for creating a user.
71
+ * @param engineCore The engine core.
72
+ * @param envVars The environment variables for the node.
73
+ * @param params The parameters for the command.
74
+ * @param params.userIdentity The DID for the user.
75
+ * @param params.organizationIdentity The organization DID for the user.
76
+ * @param params.email The email for the user.
77
+ * @param params.scope The scope for the user.
78
+ * @param params.givenName The given name for the user.
79
+ * @param params.familyName The family name for the user.
80
+ * @returns The updated user details or undefined if skipped.
81
+ */
82
+ export async function userUpdate(engineCore, envVars, params) {
83
+ Guards.email("userUpdate", "email", params.email);
84
+ if (Is.stringValue(params.userIdentity)) {
85
+ Did.guard("userUpdate", "user-identity", params.userIdentity);
86
+ }
87
+ if (Is.stringValue(params.organizationIdentity)) {
88
+ Did.guard("userUpdate", "organization-identity", params.organizationIdentity);
89
+ }
90
+ const defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType("identityProfileConnector");
91
+ const identityProfileConnector = IdentityProfileConnectorFactory.get(defaultIdentityProfileConnectorType);
92
+ const defaultAuthenticationAdminComponentType = engineCore.getRegisteredInstanceType("authenticationAdminComponent");
93
+ const authenticationAdminComponent = ComponentFactory.get(defaultAuthenticationAdminComponentType);
94
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-update.labels.updating"));
95
+ const user = {
96
+ email: params.email,
97
+ userIdentity: params.userIdentity,
98
+ organizationIdentity: params.organizationIdentity,
99
+ scope: params.scope?.split(",").map(s => s.trim())
100
+ };
101
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-update.labels.storingUser"));
102
+ const existingUser = await authenticationAdminComponent.get(params.email);
103
+ await authenticationAdminComponent.update(user);
104
+ const name = `${params.givenName ?? ""} ${params.familyName ?? ""}`.trim();
105
+ const publicProfile = {
106
+ "@context": "https://schema.org",
107
+ "@type": "Person",
108
+ name: name.length > 0 ? name : undefined
109
+ };
110
+ const privateProfile = {
111
+ "@context": "https://schema.org",
112
+ "@type": "Person",
113
+ givenName: params.givenName,
114
+ familyName: params.familyName,
115
+ email: params.email
116
+ };
117
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-update.labels.storingProfile"));
118
+ await identityProfileConnector.update(existingUser.userIdentity, publicProfile, privateProfile);
119
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.user-update.labels.userUpdated"));
120
+ CLIDisplay.break();
121
+ const json = {
122
+ did: params.userIdentity ?? existingUser.userIdentity,
123
+ organizationDid: params.organizationIdentity ?? existingUser.organizationIdentity,
124
+ email: params.email,
125
+ scope: params.scope?.split(",").map(s => s.trim()) ?? existingUser.scope,
126
+ givenName: params.givenName ?? "",
127
+ familyName: params.familyName ?? ""
128
+ };
129
+ CLIDisplay.done();
130
+ return json;
131
+ }
132
+ //# sourceMappingURL=userUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userUpdate.js","sourceRoot":"","sources":["../../../src/commands/userUpdate.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type {\n\tIAuthenticationAdminComponent,\n\tIAuthenticationUser\n} from \"@twin.org/api-auth-entity-storage-models\";\nimport { CLIDisplay } from \"@twin.org/cli-core\";\nimport { ComponentFactory, Guards, I18n, Is } from \"@twin.org/core\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport { Did, IdentityProfileConnectorFactory } from \"@twin.org/identity-models\";\nimport type { Person, WithContext } from \"schema-dts\";\nimport type { ICliCommandDefinition } from \"../models/ICliCommandDefinition.js\";\nimport type { INodeEnvironmentVariables } from \"../models/INodeEnvironmentVariables.js\";\n\nconst COMMAND_NAME = \"user-update\";\n\n/**\n * Get the command definition parameters.\n * @param commandDefinitions The registered command definitions.\n */\nexport function getCommandDefinitionUserUpdate(commandDefinitions: {\n\t[id: string]: ICliCommandDefinition;\n}): void {\n\tcommandDefinitions[COMMAND_NAME] = {\n\t\tcommand: COMMAND_NAME,\n\t\tdescription: I18n.formatMessage(\"node.cli.commands.user-update.description\"),\n\t\texample: I18n.formatMessage(\"node.cli.commands.user-update.example\"),\n\t\tparams: [\n\t\t\t{\n\t\t\t\tkey: \"env-prefix\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-update.params.env-prefix.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"user-identity\",\n\t\t\t\ttype: \"string\",\n\t\t\t\textendedType: \"DID\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-update.params.user-identity.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"organization-identity\",\n\t\t\t\ttype: \"string\",\n\t\t\t\textendedType: \"DID\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-update.params.organization-identity.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"email\",\n\t\t\t\ttype: \"string\",\n\t\t\t\textendedType: \"email\",\n\t\t\t\tdescription: I18n.formatMessage(\"node.cli.commands.user-update.params.email.description\")\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"scope\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\"node.cli.commands.user-update.params.scope.description\"),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"given-name\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-update.params.given-name.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"family-name\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-update.params.family-name.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"load-env\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.user-update.params.load-env.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t}\n\t\t],\n\t\taction: async (engineCore, envVars, params) => userUpdate(engineCore, envVars, params)\n\t};\n}\n\n/**\n * Command for creating a user.\n * @param engineCore The engine core.\n * @param envVars The environment variables for the node.\n * @param params The parameters for the command.\n * @param params.userIdentity The DID for the user.\n * @param params.organizationIdentity The organization DID for the user.\n * @param params.email The email for the user.\n * @param params.scope The scope for the user.\n * @param params.givenName The given name for the user.\n * @param params.familyName The family name for the user.\n * @returns The updated user details or undefined if skipped.\n */\nexport async function userUpdate(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tparams: {\n\t\tuserIdentity?: string;\n\t\torganizationIdentity?: string;\n\t\temail?: string;\n\t\tscope?: string;\n\t\tgivenName?: string;\n\t\tfamilyName?: string;\n\t}\n): Promise<\n\t| {\n\t\t\tdid: string;\n\t\t\torganizationDid: string;\n\t\t\temail: string;\n\t\t\tscope: string[];\n\t\t\tgivenName: string;\n\t\t\tfamilyName: string;\n\t }\n\t| undefined\n> {\n\tGuards.email(\"userUpdate\", \"email\", params.email);\n\n\tif (Is.stringValue(params.userIdentity)) {\n\t\tDid.guard(\"userUpdate\", \"user-identity\", params.userIdentity);\n\t}\n\tif (Is.stringValue(params.organizationIdentity)) {\n\t\tDid.guard(\"userUpdate\", \"organization-identity\", params.organizationIdentity);\n\t}\n\n\tconst defaultIdentityProfileConnectorType = engineCore.getRegisteredInstanceType(\n\t\t\"identityProfileConnector\"\n\t);\n\tconst identityProfileConnector = IdentityProfileConnectorFactory.get(\n\t\tdefaultIdentityProfileConnectorType\n\t);\n\n\tconst defaultAuthenticationAdminComponentType = engineCore.getRegisteredInstanceType(\n\t\t\"authenticationAdminComponent\"\n\t);\n\tconst authenticationAdminComponent = ComponentFactory.get<IAuthenticationAdminComponent>(\n\t\tdefaultAuthenticationAdminComponentType\n\t);\n\n\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-update.labels.updating\"));\n\n\tconst user: Partial<Omit<IAuthenticationUser, \"password\" | \"salt\">> = {\n\t\temail: params.email,\n\t\tuserIdentity: params.userIdentity,\n\t\torganizationIdentity: params.organizationIdentity,\n\t\tscope: params.scope?.split(\",\").map(s => s.trim())\n\t};\n\n\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-update.labels.storingUser\"));\n\n\tconst existingUser = await authenticationAdminComponent.get(params.email);\n\n\tawait authenticationAdminComponent.update(user);\n\n\tconst name = `${params.givenName ?? \"\"} ${params.familyName ?? \"\"}`.trim();\n\tconst publicProfile: WithContext<Person> = {\n\t\t\"@context\": \"https://schema.org\",\n\t\t\"@type\": \"Person\",\n\t\tname: name.length > 0 ? name : undefined\n\t};\n\tconst privateProfile: WithContext<Person> = {\n\t\t\"@context\": \"https://schema.org\",\n\t\t\"@type\": \"Person\",\n\t\tgivenName: params.givenName,\n\t\tfamilyName: params.familyName,\n\t\temail: params.email\n\t};\n\n\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-update.labels.storingProfile\"));\n\tawait identityProfileConnector.update(existingUser.userIdentity, publicProfile, privateProfile);\n\n\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.user-update.labels.userUpdated\"));\n\n\tCLIDisplay.break();\n\n\tconst json = {\n\t\tdid: params.userIdentity ?? existingUser.userIdentity,\n\t\torganizationDid: params.organizationIdentity ?? existingUser.organizationIdentity,\n\t\temail: params.email,\n\t\tscope: params.scope?.split(\",\").map(s => s.trim()) ?? existingUser.scope,\n\t\tgivenName: params.givenName ?? \"\",\n\t\tfamilyName: params.familyName ?? \"\"\n\t};\n\n\tCLIDisplay.done();\n\n\treturn json;\n}\n"]}
@@ -0,0 +1,191 @@
1
+ // Copyright 2026 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ import { CLIDisplay, CLIUtils } from "@twin.org/cli-core";
4
+ import { Converter, GeneralError, Guards, I18n, Is } from "@twin.org/core";
5
+ import { Did } from "@twin.org/identity-models";
6
+ import { VaultConnectorFactory, VaultKeyType } from "@twin.org/vault-models";
7
+ const COMMAND_NAME = "vault-key-create";
8
+ /**
9
+ * Get the command definition parameters.
10
+ * @param commandDefinitions The registered command definitions.
11
+ */
12
+ export function getCommandDefinitionVaultKeyCreate(commandDefinitions) {
13
+ commandDefinitions[COMMAND_NAME] = {
14
+ command: COMMAND_NAME,
15
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.description"),
16
+ example: I18n.formatMessage("node.cli.commands.vault-key-create.example"),
17
+ requiresNodeIdentity: false,
18
+ requiresTenantId: false,
19
+ params: [
20
+ {
21
+ key: "env-prefix",
22
+ type: "string",
23
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.env-prefix.description"),
24
+ required: false
25
+ },
26
+ {
27
+ key: "identity",
28
+ type: "string",
29
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.identity.description"),
30
+ extendedType: "did",
31
+ required: true
32
+ },
33
+ {
34
+ key: "key-id",
35
+ type: "string",
36
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.key-id.description"),
37
+ required: true
38
+ },
39
+ {
40
+ key: "key-type",
41
+ type: "string",
42
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.key-type.description"),
43
+ options: ["Ed25519", "Secp256k1", "ChaCha20Poly1305"],
44
+ defaultValue: "Ed25519",
45
+ required: false
46
+ },
47
+ {
48
+ key: "overwrite-mode",
49
+ type: "string",
50
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.overwrite-mode.description"),
51
+ options: ["skip", "overwrite", "error"],
52
+ defaultValue: "skip",
53
+ required: false
54
+ },
55
+ {
56
+ key: "load-env",
57
+ type: "string",
58
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.load-env.description"),
59
+ required: false
60
+ },
61
+ {
62
+ key: "output-json",
63
+ type: "string",
64
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.output-json.description"),
65
+ required: false
66
+ },
67
+ {
68
+ key: "output-env",
69
+ type: "string",
70
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.output-env.description"),
71
+ required: false
72
+ },
73
+ {
74
+ key: "output-env-prefix",
75
+ type: "string",
76
+ description: I18n.formatMessage("node.cli.commands.vault-key-create.params.output-env-prefix.description"),
77
+ required: false
78
+ }
79
+ ],
80
+ action: async (engineCore, envVars, params) => vaultKeyCreate(engineCore, envVars, params)
81
+ };
82
+ }
83
+ /**
84
+ * Command for creating a vault key.
85
+ * @param engineCore The engine core.
86
+ * @param envVars The environment variables for the node.
87
+ * @param params The parameters for the command.
88
+ * @param params.identity The DID to create the vault key for.
89
+ * @param params.keyId The ID of the key to create.
90
+ * @param params.keyType The type of key to create.
91
+ * @param params.overwriteMode The mode to use when a user with the same identity already exists.
92
+ * @param params.outputJson The output .json file to store the command output.
93
+ * @param params.outputEnv The output .env file to store the command output.
94
+ * @param params.outputEnvPrefix The prefix to use for variables in the output .env file.
95
+ * @returns The created vault key details or undefined if skipped.
96
+ */
97
+ export async function vaultKeyCreate(engineCore, envVars, params) {
98
+ Did.guard("vaultKeyCreate", "identity", params.identity);
99
+ Guards.stringValue("vaultKeyCreate", "key-id", params.keyId);
100
+ Guards.arrayOneOf("vaultKeyCreate", "key-type", params.keyType, [
101
+ "Ed25519",
102
+ "Secp256k1",
103
+ "ChaCha20Poly1305"
104
+ ]);
105
+ const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
106
+ const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
107
+ let createVaultKey = true;
108
+ const fullKeyId = `${params.identity}/${params.keyId}`;
109
+ let existingKey;
110
+ try {
111
+ existingKey = await vaultConnector.getKey(fullKeyId);
112
+ }
113
+ catch { }
114
+ if (!Is.empty(existingKey)) {
115
+ if (params.overwriteMode === "error") {
116
+ throw new GeneralError("vaultKeyCreate", "vaultKeyAlreadyExists");
117
+ }
118
+ else if (params.overwriteMode === "skip") {
119
+ createVaultKey = false;
120
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.vault-key-create.labels.skipping"));
121
+ }
122
+ else if (params.overwriteMode === "overwrite") {
123
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.vault-key-create.labels.overwriting"));
124
+ await vaultConnector.removeKey(fullKeyId);
125
+ }
126
+ }
127
+ let json;
128
+ if (createVaultKey) {
129
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.vault-key-create.labels.creating"));
130
+ CLIDisplay.spinnerStart();
131
+ await vaultConnector.createKey(fullKeyId, VaultKeyType[params.keyType]);
132
+ const key = await vaultConnector.getKey(fullKeyId);
133
+ CLIDisplay.spinnerStop();
134
+ CLIDisplay.task(I18n.formatMessage("node.cli.commands.vault-key-create.labels.created"));
135
+ const privateKeyBase64 = key.privateKey ? Converter.bytesToBase64(key.privateKey) : undefined;
136
+ const publicKeyBase64 = key.publicKey ? Converter.bytesToBase64(key.publicKey) : undefined;
137
+ const privateKeyHex = key.privateKey ? Converter.bytesToHex(key.privateKey, true) : undefined;
138
+ const publicKeyHex = key.publicKey ? Converter.bytesToHex(key.publicKey, true) : undefined;
139
+ CLIDisplay.break();
140
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.vault-key-create.labels.keyId"), params.keyId);
141
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.vault-key-create.labels.keyType"), params.keyType);
142
+ if (Is.stringValue(privateKeyBase64)) {
143
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.vault-key-create.labels.privateKeyBase64"), privateKeyBase64);
144
+ }
145
+ if (Is.stringValue(publicKeyBase64)) {
146
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.vault-key-create.labels.publicKeyBase64"), publicKeyBase64);
147
+ }
148
+ if (Is.stringValue(privateKeyHex)) {
149
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.vault-key-create.labels.privateKeyHex"), privateKeyHex);
150
+ }
151
+ if (Is.stringValue(publicKeyHex)) {
152
+ CLIDisplay.value(I18n.formatMessage("node.cli.commands.vault-key-create.labels.publicKeyHex"), publicKeyHex);
153
+ }
154
+ CLIDisplay.break();
155
+ json = {
156
+ identity: params.identity,
157
+ keyId: params.keyId,
158
+ keyType: params.keyType,
159
+ privateKeyBase64,
160
+ publicKeyBase64,
161
+ privateKeyHex,
162
+ publicKeyHex
163
+ };
164
+ if (Is.stringValue(params.outputJson)) {
165
+ await CLIUtils.writeJsonFile(params.outputJson, json, false);
166
+ }
167
+ if (Is.stringValue(params.outputEnv)) {
168
+ const outputParams = [
169
+ `${params.outputEnvPrefix}IDENTITY="${params.identity}"`,
170
+ `${params.outputEnvPrefix}KEY_ID="${params.keyId}"`,
171
+ `${params.outputEnvPrefix}KEY_TYPE="${params.keyType}"`
172
+ ];
173
+ if (Is.stringValue(privateKeyBase64)) {
174
+ outputParams.push(`${params.outputEnvPrefix}PRIVATE_KEY_BASE64="${privateKeyBase64}"`);
175
+ }
176
+ if (Is.stringValue(publicKeyBase64)) {
177
+ outputParams.push(`${params.outputEnvPrefix}PUBLIC_KEY_BASE64="${publicKeyBase64}"`);
178
+ }
179
+ if (Is.stringValue(privateKeyHex)) {
180
+ outputParams.push(`${params.outputEnvPrefix}PRIVATE_KEY_HEX="${privateKeyHex}"`);
181
+ }
182
+ if (Is.stringValue(publicKeyHex)) {
183
+ outputParams.push(`${params.outputEnvPrefix}PUBLIC_KEY_HEX="${publicKeyHex}"`);
184
+ }
185
+ await CLIUtils.writeEnvFile(params.outputEnv, outputParams, false);
186
+ }
187
+ }
188
+ CLIDisplay.done();
189
+ return json;
190
+ }
191
+ //# sourceMappingURL=vaultKeyCreate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vaultKeyCreate.js","sourceRoot":"","sources":["../../../src/commands/vaultKeyCreate.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { CLIDisplay, CLIUtils } from \"@twin.org/cli-core\";\nimport { Converter, GeneralError, Guards, I18n, Is } from \"@twin.org/core\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport { Did } from \"@twin.org/identity-models\";\nimport { VaultConnectorFactory, VaultKeyType } from \"@twin.org/vault-models\";\nimport type { ICliCommandDefinition } from \"../models/ICliCommandDefinition.js\";\nimport type { INodeEngineConfig } from \"../models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"../models/INodeEngineState.js\";\nimport type { INodeEnvironmentVariables } from \"../models/INodeEnvironmentVariables.js\";\n\nconst COMMAND_NAME = \"vault-key-create\";\n\n/**\n * Get the command definition parameters.\n * @param commandDefinitions The registered command definitions.\n */\nexport function getCommandDefinitionVaultKeyCreate(commandDefinitions: {\n\t[id: string]: ICliCommandDefinition;\n}): void {\n\tcommandDefinitions[COMMAND_NAME] = {\n\t\tcommand: COMMAND_NAME,\n\t\tdescription: I18n.formatMessage(\"node.cli.commands.vault-key-create.description\"),\n\t\texample: I18n.formatMessage(\"node.cli.commands.vault-key-create.example\"),\n\t\trequiresNodeIdentity: false,\n\t\trequiresTenantId: false,\n\t\tparams: [\n\t\t\t{\n\t\t\t\tkey: \"env-prefix\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.env-prefix.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"identity\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.identity.description\"\n\t\t\t\t),\n\t\t\t\textendedType: \"did\",\n\t\t\t\trequired: true\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"key-id\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.key-id.description\"\n\t\t\t\t),\n\t\t\t\trequired: true\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"key-type\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.key-type.description\"\n\t\t\t\t),\n\t\t\t\toptions: [\"Ed25519\", \"Secp256k1\", \"ChaCha20Poly1305\"],\n\t\t\t\tdefaultValue: \"Ed25519\",\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"overwrite-mode\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.overwrite-mode.description\"\n\t\t\t\t),\n\t\t\t\toptions: [\"skip\", \"overwrite\", \"error\"],\n\t\t\t\tdefaultValue: \"skip\",\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"load-env\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.load-env.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"output-json\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.output-json.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"output-env\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.output-env.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: \"output-env-prefix\",\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescription: I18n.formatMessage(\n\t\t\t\t\t\"node.cli.commands.vault-key-create.params.output-env-prefix.description\"\n\t\t\t\t),\n\t\t\t\trequired: false\n\t\t\t}\n\t\t],\n\t\taction: async (engineCore, envVars, params) => vaultKeyCreate(engineCore, envVars, params)\n\t};\n}\n\n/**\n * Command for creating a vault key.\n * @param engineCore The engine core.\n * @param envVars The environment variables for the node.\n * @param params The parameters for the command.\n * @param params.identity The DID to create the vault key for.\n * @param params.keyId The ID of the key to create.\n * @param params.keyType The type of key to create.\n * @param params.overwriteMode The mode to use when a user with the same identity already exists.\n * @param params.outputJson The output .json file to store the command output.\n * @param params.outputEnv The output .env file to store the command output.\n * @param params.outputEnvPrefix The prefix to use for variables in the output .env file.\n * @returns The created vault key details or undefined if skipped.\n */\nexport async function vaultKeyCreate(\n\tengineCore: IEngineCore<INodeEngineConfig, INodeEngineState>,\n\tenvVars: INodeEnvironmentVariables,\n\tparams: {\n\t\tidentity?: string;\n\t\tkeyType?: string;\n\t\tkeyId?: string;\n\t\toverwriteMode?: \"skip\" | \"overwrite\" | \"error\";\n\t\toutputJson?: string;\n\t\toutputEnv?: string;\n\t\toutputEnvPrefix?: string;\n\t}\n): Promise<\n\t| {\n\t\t\tidentity: string;\n\t\t\tkeyId: string;\n\t\t\tkeyType?: string;\n\t\t\tprivateKeyBase64?: string;\n\t\t\tpublicKeyBase64?: string;\n\t\t\tprivateKeyHex?: string;\n\t\t\tpublicKeyHex?: string;\n\t }\n\t| undefined\n> {\n\tDid.guard(\"vaultKeyCreate\", \"identity\", params.identity);\n\tGuards.stringValue(\"vaultKeyCreate\", \"key-id\", params.keyId);\n\tGuards.arrayOneOf(\"vaultKeyCreate\", \"key-type\", params.keyType, [\n\t\t\"Ed25519\",\n\t\t\"Secp256k1\",\n\t\t\"ChaCha20Poly1305\"\n\t]);\n\n\tconst defaultVaultConnectorType = engineCore.getRegisteredInstanceType(\"vaultConnector\");\n\tconst vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);\n\n\tlet createVaultKey = true;\n\tconst fullKeyId = `${params.identity}/${params.keyId}`;\n\n\tlet existingKey;\n\ttry {\n\t\texistingKey = await vaultConnector.getKey(fullKeyId);\n\t} catch {}\n\n\tif (!Is.empty(existingKey)) {\n\t\tif (params.overwriteMode === \"error\") {\n\t\t\tthrow new GeneralError(\"vaultKeyCreate\", \"vaultKeyAlreadyExists\");\n\t\t} else if (params.overwriteMode === \"skip\") {\n\t\t\tcreateVaultKey = false;\n\t\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.vault-key-create.labels.skipping\"));\n\t\t} else if (params.overwriteMode === \"overwrite\") {\n\t\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.vault-key-create.labels.overwriting\"));\n\t\t\tawait vaultConnector.removeKey(fullKeyId);\n\t\t}\n\t}\n\n\tlet json;\n\tif (createVaultKey) {\n\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.vault-key-create.labels.creating\"));\n\t\tCLIDisplay.spinnerStart();\n\n\t\tawait vaultConnector.createKey(\n\t\t\tfullKeyId,\n\t\t\tVaultKeyType[params.keyType as keyof typeof VaultKeyType]\n\t\t);\n\n\t\tconst key = await vaultConnector.getKey(fullKeyId);\n\n\t\tCLIDisplay.spinnerStop();\n\t\tCLIDisplay.task(I18n.formatMessage(\"node.cli.commands.vault-key-create.labels.created\"));\n\n\t\tconst privateKeyBase64 = key.privateKey ? Converter.bytesToBase64(key.privateKey) : undefined;\n\t\tconst publicKeyBase64 = key.publicKey ? Converter.bytesToBase64(key.publicKey) : undefined;\n\t\tconst privateKeyHex = key.privateKey ? Converter.bytesToHex(key.privateKey, true) : undefined;\n\t\tconst publicKeyHex = key.publicKey ? Converter.bytesToHex(key.publicKey, true) : undefined;\n\n\t\tCLIDisplay.break();\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"node.cli.commands.vault-key-create.labels.keyId\"),\n\t\t\tparams.keyId\n\t\t);\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"node.cli.commands.vault-key-create.labels.keyType\"),\n\t\t\tparams.keyType\n\t\t);\n\t\tif (Is.stringValue(privateKeyBase64)) {\n\t\t\tCLIDisplay.value(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.vault-key-create.labels.privateKeyBase64\"),\n\t\t\t\tprivateKeyBase64\n\t\t\t);\n\t\t}\n\t\tif (Is.stringValue(publicKeyBase64)) {\n\t\t\tCLIDisplay.value(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.vault-key-create.labels.publicKeyBase64\"),\n\t\t\t\tpublicKeyBase64\n\t\t\t);\n\t\t}\n\t\tif (Is.stringValue(privateKeyHex)) {\n\t\t\tCLIDisplay.value(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.vault-key-create.labels.privateKeyHex\"),\n\t\t\t\tprivateKeyHex\n\t\t\t);\n\t\t}\n\t\tif (Is.stringValue(publicKeyHex)) {\n\t\t\tCLIDisplay.value(\n\t\t\t\tI18n.formatMessage(\"node.cli.commands.vault-key-create.labels.publicKeyHex\"),\n\t\t\t\tpublicKeyHex\n\t\t\t);\n\t\t}\n\n\t\tCLIDisplay.break();\n\n\t\tjson = {\n\t\t\tidentity: params.identity,\n\t\t\tkeyId: params.keyId,\n\t\t\tkeyType: params.keyType,\n\t\t\tprivateKeyBase64,\n\t\t\tpublicKeyBase64,\n\t\t\tprivateKeyHex,\n\t\t\tpublicKeyHex\n\t\t};\n\t\tif (Is.stringValue(params.outputJson)) {\n\t\t\tawait CLIUtils.writeJsonFile(params.outputJson, json, false);\n\t\t}\n\n\t\tif (Is.stringValue(params.outputEnv)) {\n\t\t\tconst outputParams = [\n\t\t\t\t`${params.outputEnvPrefix}IDENTITY=\"${params.identity}\"`,\n\t\t\t\t`${params.outputEnvPrefix}KEY_ID=\"${params.keyId}\"`,\n\t\t\t\t`${params.outputEnvPrefix}KEY_TYPE=\"${params.keyType}\"`\n\t\t\t];\n\n\t\t\tif (Is.stringValue(privateKeyBase64)) {\n\t\t\t\toutputParams.push(`${params.outputEnvPrefix}PRIVATE_KEY_BASE64=\"${privateKeyBase64}\"`);\n\t\t\t}\n\n\t\t\tif (Is.stringValue(publicKeyBase64)) {\n\t\t\t\toutputParams.push(`${params.outputEnvPrefix}PUBLIC_KEY_BASE64=\"${publicKeyBase64}\"`);\n\t\t\t}\n\t\t\tif (Is.stringValue(privateKeyHex)) {\n\t\t\t\toutputParams.push(`${params.outputEnvPrefix}PRIVATE_KEY_HEX=\"${privateKeyHex}\"`);\n\t\t\t}\n\t\t\tif (Is.stringValue(publicKeyHex)) {\n\t\t\t\toutputParams.push(`${params.outputEnvPrefix}PUBLIC_KEY_HEX=\"${publicKeyHex}\"`);\n\t\t\t}\n\t\t\tawait CLIUtils.writeEnvFile(params.outputEnv, outputParams, false);\n\t\t}\n\t}\n\n\tCLIDisplay.done();\n\n\treturn json;\n}\n"]}