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

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.
@@ -118,13 +118,15 @@ export async function bootstrapNodeAdminUser(engineCore, context, envVars, featu
118
118
  if (defaultAuthenticationComponentType.startsWith(AuthenticationComponentType.EntityStorage) &&
119
119
  Is.stringValue(context.state.nodeId)) {
120
120
  const authUserEntityStorage = EntityStorageConnectorFactory.get("authentication-user");
121
- // If we don't have an organization identity, create one
122
- if (!Is.stringValue(context.state.nodeOrganizationId)) {
123
- context.state.nodeOrganizationId = await createIdentity(engineCore, envVars, context.state.nodeOrganizationId, envVars.organizationMnemonic, context.state.nodeId, "organization", features.includes(NodeFeatures.NodeWallet));
121
+ const existingOrganizationId = envVars.organizationIdentity ?? context.state.nodeOrganizationId;
122
+ const orgId = await createIdentity(engineCore, envVars, existingOrganizationId, envVars.organizationMnemonic, existingOrganizationId, "organization", features.includes(NodeFeatures.NodeWallet));
123
+ if (context.state.nodeOrganizationId !== orgId) {
124
+ context.state.nodeOrganizationId = orgId;
124
125
  context.stateDirty = true;
125
126
  }
126
- if (!Is.stringValue(context.state.nodeAdminUserId)) {
127
- context.state.nodeAdminUserId = await createIdentity(engineCore, envVars, context.state.nodeAdminUserId, envVars.adminUserMnemonic, context.state.nodeOrganizationId, "user", false);
127
+ const userId = await createIdentity(engineCore, envVars, context.state.nodeAdminUserId, envVars.adminUserMnemonic, context.state.nodeOrganizationId, "user", false);
128
+ if (context.state.nodeAdminUserId !== userId) {
129
+ context.state.nodeAdminUserId = userId;
128
130
  context.stateDirty = true;
129
131
  }
130
132
  const adminEmail = envVars.adminUserName ?? DEFAULT_NODE_ADMIN_USERNAME;
@@ -144,7 +146,11 @@ export async function bootstrapNodeAdminUser(engineCore, context, envVars, featu
144
146
  organization: context.state.nodeOrganizationId
145
147
  };
146
148
  engineCore.logInfo(I18n.formatMessage("node.nodeAdminUserEmail", { email: adminEmail }));
147
- engineCore.logInfo(I18n.formatMessage("node.nodeAdminUserPassword", { password: generatedPassword }));
149
+ const defaultVaultConnectorType = engineCore.getRegisteredInstanceType("vaultConnector");
150
+ const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
151
+ const vaultKey = `${context.state.nodeAdminUserId}/admin-password`;
152
+ await vaultConnector.setSecret(vaultKey, generatedPassword);
153
+ engineCore.logInfo(I18n.formatMessage("node.nodeAdminUserPassword", { vaultKey }));
148
154
  await authUserEntityStorage.set(nodeAdminUser);
149
155
  }
150
156
  else {
@@ -1 +1 @@
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,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,cAAc,CAC1C,UAAU,EACV,OAAO,EACP,cAAc,EACd,OAAO,CAAC,YAAY,EACpB,cAAc,EACd,MAAM,EACN,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAC1C,CAAC;QACF,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;QAE1B,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE;YACjC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;SAC9B,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,IAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;QAE9D,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,+BAA+B,GACpC,UAAU,CAAC,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;YAE9D,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,CAC9C,+BAA+B,CAC/B,CAAC;YAEF,QAAQ,GAAG,cAAc,CAAC,gBAAgB,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,IAAI,cAAc,CAAC,cAAc,EAAE,CAAC;YAEvE,MAAM,kBAAkB,CAAC,GAAG,CAAC;gBAC5B,EAAE,EAAE,QAAQ;gBACZ,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,QAAQ;gBAClB,MAAM;aACN,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE;gBAC3C,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY;aACpC,CAAC,CACF,CAAC;QACH,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC;QACtC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;QAE1B,UAAU,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC3E,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,wDAAwD;YACxD,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACvD,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,MAAM,cAAc,CACtD,UAAU,EACV,OAAO,EACP,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAChC,OAAO,CAAC,oBAAoB,EAC5B,OAAO,CAAC,KAAK,CAAC,MAAM,EACpB,cAAc,EACd,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAC1C,CAAC;gBACF,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,CAAC;YAED,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;gBACpD,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,MAAM,cAAc,CACnD,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;gBACF,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;gBACzF,UAAU,CAAC,OAAO,CACjB,IAAI,CAAC,aAAa,CAAC,4BAA4B,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CACjF,CAAC;gBAEF,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\tcontext.state.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\t\tcontext.stateDirty = true;\n\n\t\tengineCore.logInfo(\n\t\t\tI18n.formatMessage(\"node.nodeId\", {\n\t\t\t\tidentity: context.state.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\tlet tenantId = envVars.tenantId ?? context.state.nodeTenantId;\n\n\t\tif (!Is.stringValue(tenantId)) {\n\t\t\tconst tenantAdminServiceComponentType =\n\t\t\t\tengineCore.getRegisteredInstanceType(\"tenantAdminComponent\");\n\n\t\t\tconst tenantAdminService = ComponentFactory.get<ITenantAdminComponent>(\n\t\t\t\ttenantAdminServiceComponentType\n\t\t\t);\n\n\t\t\ttenantId = TenantIdHelper.generateTenantId();\n\t\t\tconst apiKey = envVars.tenantApiKey ?? TenantIdHelper.generateApiKey();\n\n\t\t\tawait tenantAdminService.set({\n\t\t\t\tid: tenantId,\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\tidentity: tenantId,\n\t\t\t\t\tapiKey\n\t\t\t\t})\n\t\t\t);\n\t\t} else {\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.existingTenantId\", {\n\t\t\t\t\tidentity: context.state.nodeTenantId\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\n\t\tcontext.state.nodeTenantId = tenantId;\n\t\tcontext.stateDirty = true;\n\n\t\tengineCore.addContextId(ContextIdKeys.Tenant, context.state.nodeTenantId);\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\t// If we don't have an organization identity, create one\n\t\t\tif (!Is.stringValue(context.state.nodeOrganizationId)) {\n\t\t\t\tcontext.state.nodeOrganizationId = await createIdentity(\n\t\t\t\t\tengineCore,\n\t\t\t\t\tenvVars,\n\t\t\t\t\tcontext.state.nodeOrganizationId,\n\t\t\t\t\tenvVars.organizationMnemonic,\n\t\t\t\t\tcontext.state.nodeId,\n\t\t\t\t\t\"organization\",\n\t\t\t\t\tfeatures.includes(NodeFeatures.NodeWallet)\n\t\t\t\t);\n\t\t\t\tcontext.stateDirty = true;\n\t\t\t}\n\n\t\t\tif (!Is.stringValue(context.state.nodeAdminUserId)) {\n\t\t\t\tcontext.state.nodeAdminUserId = await createIdentity(\n\t\t\t\t\tengineCore,\n\t\t\t\t\tenvVars,\n\t\t\t\t\tcontext.state.nodeAdminUserId,\n\t\t\t\t\tenvVars.adminUserMnemonic,\n\t\t\t\t\tcontext.state.nodeOrganizationId,\n\t\t\t\t\t\"user\",\n\t\t\t\t\tfalse\n\t\t\t\t);\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\t\t\t\tengineCore.logInfo(\n\t\t\t\t\tI18n.formatMessage(\"node.nodeAdminUserPassword\", { password: generatedPassword })\n\t\t\t\t);\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"]}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"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","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\tcontext.state.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\t\tcontext.stateDirty = true;\n\n\t\tengineCore.logInfo(\n\t\t\tI18n.formatMessage(\"node.nodeId\", {\n\t\t\t\tidentity: context.state.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\tlet tenantId = envVars.tenantId ?? context.state.nodeTenantId;\n\n\t\tif (!Is.stringValue(tenantId)) {\n\t\t\tconst tenantAdminServiceComponentType =\n\t\t\t\tengineCore.getRegisteredInstanceType(\"tenantAdminComponent\");\n\n\t\t\tconst tenantAdminService = ComponentFactory.get<ITenantAdminComponent>(\n\t\t\t\ttenantAdminServiceComponentType\n\t\t\t);\n\n\t\t\ttenantId = TenantIdHelper.generateTenantId();\n\t\t\tconst apiKey = envVars.tenantApiKey ?? TenantIdHelper.generateApiKey();\n\n\t\t\tawait tenantAdminService.set({\n\t\t\t\tid: tenantId,\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\tidentity: tenantId,\n\t\t\t\t\tapiKey\n\t\t\t\t})\n\t\t\t);\n\t\t} else {\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.existingTenantId\", {\n\t\t\t\t\tidentity: context.state.nodeTenantId\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\n\t\tcontext.state.nodeTenantId = tenantId;\n\t\tcontext.stateDirty = true;\n\n\t\tengineCore.addContextId(ContextIdKeys.Tenant, context.state.nodeTenantId);\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"]}
@@ -1,6 +1,6 @@
1
1
  // Copyright 2024 IOTA Stiftung.
2
2
  // SPDX-License-Identifier: Apache-2.0.
3
- import { Converter, I18n, Is, RandomHelper, Urn } from "@twin.org/core";
3
+ import { Converter, I18n, Is, RandomHelper, StringHelper, Urn } from "@twin.org/core";
4
4
  import { Bip39 } from "@twin.org/crypto";
5
5
  import { IdentityConnectorType, WalletConnectorType } from "@twin.org/engine-types";
6
6
  import { EntityStorageConnectorFactory } from "@twin.org/entity-storage-models";
@@ -27,9 +27,12 @@ export async function createIdentity(engineCore, envVars, configIdentity, config
27
27
  const vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);
28
28
  const workingIdentity = configIdentity ?? `bootstrap-temp-${Converter.bytesToHex(RandomHelper.generate(16))}`;
29
29
  const workingController = controller ?? workingIdentity;
30
- await bootstrapMnemonic(engineCore, vaultConnector, workingIdentity, configMnemonic);
30
+ const mnemonicStored = await bootstrapMnemonic(engineCore, vaultConnector, workingIdentity, configMnemonic);
31
31
  const addresses = addWallet ? await generateWallet(engineCore, envVars, workingIdentity) : [];
32
32
  const finalIdentity = await generateIdentity(engineCore, envVars, workingController, workingIdentity, identityType);
33
+ if (mnemonicStored) {
34
+ engineCore.logInfo(I18n.formatMessage("node.finalMnemonic", { vaultKey: `${finalIdentity}/mnemonic` }));
35
+ }
33
36
  await finaliseWallet(engineCore, envVars, finalIdentity, addresses);
34
37
  await finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity);
35
38
  return finalIdentity;
@@ -40,14 +43,21 @@ export async function createIdentity(engineCore, envVars, configIdentity, config
40
43
  * @param vaultConnector The vault connector to use.
41
44
  * @param identity The identity of the node.
42
45
  * @param existingMnemonic An existing mnemonic to use.
46
+ * @returns Whether the mnemonic was stored.
43
47
  */
44
48
  async function bootstrapMnemonic(engineCore, vaultConnector, identity, existingMnemonic) {
45
49
  let mnemonic = existingMnemonic;
46
50
  let storeMnemonic = false;
51
+ const mnemonicKey = `${identity}/mnemonic`;
47
52
  try {
48
- const storedMnemonic = await vaultConnector.getSecret(`${identity}/mnemonic`);
49
- storeMnemonic = storedMnemonic !== mnemonic;
50
- mnemonic = storedMnemonic;
53
+ const storedMnemonic = await vaultConnector.getSecret(mnemonicKey);
54
+ if (Is.stringValue(storedMnemonic)) {
55
+ storeMnemonic = storedMnemonic !== mnemonic && !Is.empty(mnemonic);
56
+ mnemonic = storedMnemonic;
57
+ }
58
+ else {
59
+ storeMnemonic = true;
60
+ }
51
61
  }
52
62
  catch {
53
63
  storeMnemonic = true;
@@ -56,16 +66,16 @@ async function bootstrapMnemonic(engineCore, vaultConnector, identity, existingM
56
66
  if (Is.empty(mnemonic)) {
57
67
  mnemonic = Bip39.randomMnemonic();
58
68
  storeMnemonic = true;
59
- engineCore.logInfo(I18n.formatMessage("node.generatingMnemonic", { mnemonic }));
60
69
  }
61
70
  // If there is no mnemonic stored in the vault then we need to store it
62
71
  if (storeMnemonic) {
63
72
  engineCore.logInfo(I18n.formatMessage("node.storingMnemonic"));
64
- await vaultConnector.setSecret(`${identity}/mnemonic`, mnemonic);
73
+ await vaultConnector.setSecret(mnemonicKey, mnemonic);
65
74
  }
66
75
  else {
67
76
  engineCore.logInfo(I18n.formatMessage("node.existingMnemonic"));
68
77
  }
78
+ return storeMnemonic;
69
79
  }
70
80
  /**
71
81
  * Finalise the mnemonic for the node identity.
@@ -118,8 +128,9 @@ async function generateWallet(engineCore, envVars, identity) {
118
128
  const balance = await walletConnector.getBalance(identity, addresses[0]);
119
129
  if (balance === 0n) {
120
130
  let address0 = addresses[0];
121
- if (defaultWalletConnectorType.startsWith(WalletConnectorType.Iota)) {
122
- address0 = `${envVars.iotaExplorerEndpoint}address/${address0}?network=${envVars.iotaNetwork}`;
131
+ if (defaultWalletConnectorType.startsWith(WalletConnectorType.Iota) &&
132
+ Is.stringValue(envVars.iotaExplorerEndpoint)) {
133
+ address0 = `${StringHelper.trimTrailingSlashes(envVars.iotaExplorerEndpoint)}/address/${address0}?network=${envVars.iotaNetwork}`;
123
134
  }
124
135
  engineCore.logInfo(I18n.formatMessage("node.fundingWallet", { address: address0 }));
125
136
  // Add some funds to the wallet from the faucet
@@ -160,9 +171,11 @@ async function generateIdentity(engineCore, envVars, controller, identity, ident
160
171
  const didUrn = Urn.fromValidString(identityDocument.id);
161
172
  const didParts = didUrn.parts();
162
173
  const objectId = didParts[3];
163
- engineCore.logInfo(I18n.formatMessage("node.identityExplorer", {
164
- url: `${envVars.iotaExplorerEndpoint}object/${objectId}?network=${envVars.iotaNetwork}`
165
- }));
174
+ if (Is.stringValue(envVars.iotaExplorerEndpoint)) {
175
+ engineCore.logInfo(I18n.formatMessage("node.identityExplorer", {
176
+ url: `${StringHelper.trimTrailingSlashes(envVars.iotaExplorerEndpoint)}/object/${objectId}?network=${envVars.iotaNetwork}`
177
+ }));
178
+ }
166
179
  }
167
180
  return identityDocument.id;
168
181
  }
@@ -1 +1 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Converter, I18n, Is, RandomHelper, Urn } from \"@twin.org/core\";\nimport { Bip39 } from \"@twin.org/crypto\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport { IdentityConnectorType, WalletConnectorType } from \"@twin.org/engine-types\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport {\n\tIdentityConnectorFactory,\n\tIdentityResolverConnectorFactory\n} from \"@twin.org/identity-models\";\nimport { nameofKebabCase } from \"@twin.org/nameof\";\nimport { type IVaultConnector, VaultConnectorFactory } from \"@twin.org/vault-models\";\nimport type { WalletAddress } from \"@twin.org/wallet-connector-entity-storage\";\nimport { WalletConnectorFactory } from \"@twin.org/wallet-models\";\nimport type { INodeEnvironmentVariables } from \"./models/INodeEnvironmentVariables.js\";\n\n/**\n * Generate an identity and fund it.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param configIdentity A identity from config to use.\n * @param configMnemonic A mnemonic from config to use.\n * @param controller The controller for the identity.\n * @param identityType The type of identity.\n * @param addWallet Whether to add a wallet for the identity.\n * @returns The identity that was generated.\n */\nexport async function createIdentity(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tconfigIdentity: string | undefined,\n\tconfigMnemonic: string | undefined,\n\tcontroller: string | undefined,\n\tidentityType: \"node\" | \"organization\" | \"user\",\n\taddWallet: boolean\n): Promise<string> {\n\tengineCore.logInfo(I18n.formatMessage(\"node.processingIdentity\", { identityType }));\n\n\t// We have a chicken and egg problem in that we can't create the identity\n\t// to store the mnemonic in the vault without an identity. We use a temporary identity\n\t// and then replace it with the new identity later in the process.\n\tconst defaultVaultConnectorType = engineCore.getRegisteredInstanceType(\"vaultConnector\");\n\tconst vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);\n\n\tconst workingIdentity =\n\t\tconfigIdentity ?? `bootstrap-temp-${Converter.bytesToHex(RandomHelper.generate(16))}`;\n\tconst workingController = controller ?? workingIdentity;\n\n\tawait bootstrapMnemonic(engineCore, vaultConnector, workingIdentity, configMnemonic);\n\n\tconst addresses = addWallet ? await generateWallet(engineCore, envVars, workingIdentity) : [];\n\n\tconst finalIdentity = await generateIdentity(\n\t\tengineCore,\n\t\tenvVars,\n\t\tworkingController,\n\t\tworkingIdentity,\n\t\tidentityType\n\t);\n\n\tawait finaliseWallet(engineCore, envVars, finalIdentity, addresses);\n\n\tawait finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity);\n\n\treturn finalIdentity;\n}\n\n/**\n * Generate a mnemonic for the node identity.\n * @param engineCore The engine core for the node.\n * @param vaultConnector The vault connector to use.\n * @param identity The identity of the node.\n * @param existingMnemonic An existing mnemonic to use.\n */\nasync function bootstrapMnemonic(\n\tengineCore: IEngineCore,\n\tvaultConnector: IVaultConnector,\n\tidentity: string,\n\texistingMnemonic?: string\n): Promise<void> {\n\tlet mnemonic = existingMnemonic;\n\tlet storeMnemonic = false;\n\n\ttry {\n\t\tconst storedMnemonic = await vaultConnector.getSecret<string>(`${identity}/mnemonic`);\n\t\tstoreMnemonic = storedMnemonic !== mnemonic;\n\t\tmnemonic = storedMnemonic;\n\t} catch {\n\t\tstoreMnemonic = true;\n\t}\n\n\t// If there is no mnemonic then we need to generate one\n\tif (Is.empty(mnemonic)) {\n\t\tmnemonic = Bip39.randomMnemonic();\n\t\tstoreMnemonic = true;\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.generatingMnemonic\", { mnemonic }));\n\t}\n\n\t// If there is no mnemonic stored in the vault then we need to store it\n\tif (storeMnemonic) {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.storingMnemonic\"));\n\t\tawait vaultConnector.setSecret(`${identity}/mnemonic`, mnemonic);\n\t} else {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.existingMnemonic\"));\n\t}\n}\n\n/**\n * Finalise the mnemonic for the node identity.\n * @param vaultConnector The vault connector to use.\n * @param workingIdentity The identity of the node.\n * @param finalIdentity The final identity for the node.\n */\nasync function finaliseMnemonic(\n\tvaultConnector: IVaultConnector,\n\tworkingIdentity: string,\n\tfinalIdentity: string\n): Promise<void> {\n\t// Now that we have an identity we can remove the temporary one\n\t// and store the mnemonic with the new identity\n\tif (workingIdentity.startsWith(\"bootstrap-temp-\") && workingIdentity !== finalIdentity) {\n\t\tconst mnemonic = await vaultConnector.getSecret(`${workingIdentity}/mnemonic`);\n\t\tawait vaultConnector.setSecret(`${finalIdentity}/mnemonic`, mnemonic);\n\t\tawait vaultConnector.removeSecret(`${workingIdentity}/mnemonic`);\n\t}\n}\n\n/**\n * Bootstrap the identity for the node.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param finalIdentity The identity of the node.\n * @param addresses The addresses for the wallet.\n */\nasync function finaliseWallet(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tfinalIdentity: string,\n\taddresses: string[]\n): Promise<void> {\n\tif (Is.arrayValue(addresses)) {\n\t\tconst defaultWalletConnectorType = engineCore.getRegisteredInstanceType(\"walletConnector\");\n\n\t\t// If we are using entity storage for wallet the identity associated with the\n\t\t// address will be wrong, so fix it\n\t\tif (defaultWalletConnectorType.startsWith(WalletConnectorType.EntityStorage)) {\n\t\t\tconst walletAddress =\n\t\t\t\tEntityStorageConnectorFactory.get<IEntityStorageConnector<WalletAddress>>(\n\t\t\t\t\tnameofKebabCase<WalletAddress>()\n\t\t\t\t);\n\t\t\tconst addr = await walletAddress.get(addresses[0]);\n\t\t\tif (!Is.empty(addr)) {\n\t\t\t\taddr.identity = finalIdentity;\n\t\t\t\tawait walletAddress.set(addr);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Bootstrap the wallet for the node.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param identity The identity to create the wallet for.\n * @returns The addresses for the wallet.\n */\nasync function generateWallet(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tidentity: string\n): Promise<string[]> {\n\tconst defaultWalletConnectorType = engineCore.getRegisteredInstanceType(\"walletConnector\");\n\n\tconst walletConnector = WalletConnectorFactory.get(defaultWalletConnectorType);\n\tconst addresses = await walletConnector.getAddresses(identity, 0, 0, 5);\n\n\tconst balance = await walletConnector.getBalance(identity, addresses[0]);\n\tif (balance === 0n) {\n\t\tlet address0 = addresses[0];\n\n\t\tif (defaultWalletConnectorType.startsWith(WalletConnectorType.Iota)) {\n\t\t\taddress0 = `${envVars.iotaExplorerEndpoint}address/${address0}?network=${envVars.iotaNetwork}`;\n\t\t}\n\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.fundingWallet\", { address: address0 }));\n\n\t\t// Add some funds to the wallet from the faucet\n\t\tawait walletConnector.ensureBalance(identity, addresses[0], 1000000000n);\n\t} else {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.fundedWallet\"));\n\t}\n\treturn addresses;\n}\n\n/**\n * Bootstrap the identity for the node.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param controller The controller for the identity.\n * @param identity The existing identity if there is one.\n * @param identityType The type of identity.\n * @returns The addresses for the wallet.\n */\nasync function generateIdentity(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tcontroller: string,\n\tidentity: string,\n\tidentityType: \"node\" | \"organization\" | \"user\"\n): Promise<string> {\n\tconst defaultIdentityConnectorType = engineCore.getRegisteredInstanceType(\"identityConnector\");\n\n\t// Now create an identity for the node controlled by the address we just funded\n\tconst identityConnector = IdentityConnectorFactory.get(defaultIdentityConnectorType);\n\n\tlet identityDocument;\n\n\ttry {\n\t\tconst defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType(\n\t\t\t\"identityResolverConnector\"\n\t\t);\n\n\t\tconst identityResolverConnector = IdentityResolverConnectorFactory.get(\n\t\t\tdefaultIdentityResolverConnectorType\n\t\t);\n\t\tidentityDocument = await identityResolverConnector.resolveDocument(identity);\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.existingIdentity\", { identity }));\n\t} catch {}\n\n\tif (Is.empty(identityDocument)) {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.generatingIdentity\", { identityType }));\n\n\t\tidentityDocument = await identityConnector.createDocument(controller);\n\n\t\tengineCore.logInfo(\n\t\t\tI18n.formatMessage(\"node.createdIdentity\", { identity: identityDocument.id })\n\t\t);\n\t}\n\n\tif (defaultIdentityConnectorType.startsWith(IdentityConnectorType.Iota)) {\n\t\tconst didUrn = Urn.fromValidString(identityDocument.id);\n\t\tconst didParts = didUrn.parts();\n\t\tconst objectId = didParts[3];\n\n\t\tengineCore.logInfo(\n\t\t\tI18n.formatMessage(\"node.identityExplorer\", {\n\t\t\t\turl: `${envVars.iotaExplorerEndpoint}object/${objectId}?network=${envVars.iotaNetwork}`\n\t\t\t})\n\t\t);\n\t}\n\treturn identityDocument.id;\n}\n"]}
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Converter, I18n, Is, RandomHelper, StringHelper, Urn } from \"@twin.org/core\";\nimport { Bip39 } from \"@twin.org/crypto\";\nimport type { IEngineCore } from \"@twin.org/engine-models\";\nimport { IdentityConnectorType, WalletConnectorType } from \"@twin.org/engine-types\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport {\n\tIdentityConnectorFactory,\n\tIdentityResolverConnectorFactory\n} from \"@twin.org/identity-models\";\nimport { nameofKebabCase } from \"@twin.org/nameof\";\nimport { type IVaultConnector, VaultConnectorFactory } from \"@twin.org/vault-models\";\nimport type { WalletAddress } from \"@twin.org/wallet-connector-entity-storage\";\nimport { WalletConnectorFactory } from \"@twin.org/wallet-models\";\nimport type { INodeEnvironmentVariables } from \"./models/INodeEnvironmentVariables.js\";\n\n/**\n * Generate an identity and fund it.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param configIdentity A identity from config to use.\n * @param configMnemonic A mnemonic from config to use.\n * @param controller The controller for the identity.\n * @param identityType The type of identity.\n * @param addWallet Whether to add a wallet for the identity.\n * @returns The identity that was generated.\n */\nexport async function createIdentity(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tconfigIdentity: string | undefined,\n\tconfigMnemonic: string | undefined,\n\tcontroller: string | undefined,\n\tidentityType: \"node\" | \"organization\" | \"user\",\n\taddWallet: boolean\n): Promise<string> {\n\tengineCore.logInfo(I18n.formatMessage(\"node.processingIdentity\", { identityType }));\n\n\t// We have a chicken and egg problem in that we can't create the identity\n\t// to store the mnemonic in the vault without an identity. We use a temporary identity\n\t// and then replace it with the new identity later in the process.\n\tconst defaultVaultConnectorType = engineCore.getRegisteredInstanceType(\"vaultConnector\");\n\tconst vaultConnector = VaultConnectorFactory.get(defaultVaultConnectorType);\n\n\tconst workingIdentity =\n\t\tconfigIdentity ?? `bootstrap-temp-${Converter.bytesToHex(RandomHelper.generate(16))}`;\n\tconst workingController = controller ?? workingIdentity;\n\n\tconst mnemonicStored = await bootstrapMnemonic(\n\t\tengineCore,\n\t\tvaultConnector,\n\t\tworkingIdentity,\n\t\tconfigMnemonic\n\t);\n\n\tconst addresses = addWallet ? await generateWallet(engineCore, envVars, workingIdentity) : [];\n\n\tconst finalIdentity = await generateIdentity(\n\t\tengineCore,\n\t\tenvVars,\n\t\tworkingController,\n\t\tworkingIdentity,\n\t\tidentityType\n\t);\n\n\tif (mnemonicStored) {\n\t\tengineCore.logInfo(\n\t\t\tI18n.formatMessage(\"node.finalMnemonic\", { vaultKey: `${finalIdentity}/mnemonic` })\n\t\t);\n\t}\n\n\tawait finaliseWallet(engineCore, envVars, finalIdentity, addresses);\n\n\tawait finaliseMnemonic(vaultConnector, workingIdentity, finalIdentity);\n\n\treturn finalIdentity;\n}\n\n/**\n * Generate a mnemonic for the node identity.\n * @param engineCore The engine core for the node.\n * @param vaultConnector The vault connector to use.\n * @param identity The identity of the node.\n * @param existingMnemonic An existing mnemonic to use.\n * @returns Whether the mnemonic was stored.\n */\nasync function bootstrapMnemonic(\n\tengineCore: IEngineCore,\n\tvaultConnector: IVaultConnector,\n\tidentity: string,\n\texistingMnemonic?: string\n): Promise<boolean> {\n\tlet mnemonic = existingMnemonic;\n\tlet storeMnemonic = false;\n\n\tconst mnemonicKey = `${identity}/mnemonic`;\n\n\ttry {\n\t\tconst storedMnemonic = await vaultConnector.getSecret<string>(mnemonicKey);\n\t\tif (Is.stringValue(storedMnemonic)) {\n\t\t\tstoreMnemonic = storedMnemonic !== mnemonic && !Is.empty(mnemonic);\n\t\t\tmnemonic = storedMnemonic;\n\t\t} else {\n\t\t\tstoreMnemonic = true;\n\t\t}\n\t} catch {\n\t\tstoreMnemonic = true;\n\t}\n\n\t// If there is no mnemonic then we need to generate one\n\tif (Is.empty(mnemonic)) {\n\t\tmnemonic = Bip39.randomMnemonic();\n\t\tstoreMnemonic = true;\n\t}\n\n\t// If there is no mnemonic stored in the vault then we need to store it\n\tif (storeMnemonic) {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.storingMnemonic\"));\n\t\tawait vaultConnector.setSecret(mnemonicKey, mnemonic);\n\t} else {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.existingMnemonic\"));\n\t}\n\n\treturn storeMnemonic;\n}\n\n/**\n * Finalise the mnemonic for the node identity.\n * @param vaultConnector The vault connector to use.\n * @param workingIdentity The identity of the node.\n * @param finalIdentity The final identity for the node.\n */\nasync function finaliseMnemonic(\n\tvaultConnector: IVaultConnector,\n\tworkingIdentity: string,\n\tfinalIdentity: string\n): Promise<void> {\n\t// Now that we have an identity we can remove the temporary one\n\t// and store the mnemonic with the new identity\n\tif (workingIdentity.startsWith(\"bootstrap-temp-\") && workingIdentity !== finalIdentity) {\n\t\tconst mnemonic = await vaultConnector.getSecret(`${workingIdentity}/mnemonic`);\n\t\tawait vaultConnector.setSecret(`${finalIdentity}/mnemonic`, mnemonic);\n\t\tawait vaultConnector.removeSecret(`${workingIdentity}/mnemonic`);\n\t}\n}\n\n/**\n * Bootstrap the identity for the node.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param finalIdentity The identity of the node.\n * @param addresses The addresses for the wallet.\n */\nasync function finaliseWallet(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tfinalIdentity: string,\n\taddresses: string[]\n): Promise<void> {\n\tif (Is.arrayValue(addresses)) {\n\t\tconst defaultWalletConnectorType = engineCore.getRegisteredInstanceType(\"walletConnector\");\n\n\t\t// If we are using entity storage for wallet the identity associated with the\n\t\t// address will be wrong, so fix it\n\t\tif (defaultWalletConnectorType.startsWith(WalletConnectorType.EntityStorage)) {\n\t\t\tconst walletAddress =\n\t\t\t\tEntityStorageConnectorFactory.get<IEntityStorageConnector<WalletAddress>>(\n\t\t\t\t\tnameofKebabCase<WalletAddress>()\n\t\t\t\t);\n\t\t\tconst addr = await walletAddress.get(addresses[0]);\n\t\t\tif (!Is.empty(addr)) {\n\t\t\t\taddr.identity = finalIdentity;\n\t\t\t\tawait walletAddress.set(addr);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Bootstrap the wallet for the node.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param identity The identity to create the wallet for.\n * @returns The addresses for the wallet.\n */\nasync function generateWallet(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tidentity: string\n): Promise<string[]> {\n\tconst defaultWalletConnectorType = engineCore.getRegisteredInstanceType(\"walletConnector\");\n\n\tconst walletConnector = WalletConnectorFactory.get(defaultWalletConnectorType);\n\tconst addresses = await walletConnector.getAddresses(identity, 0, 0, 5);\n\n\tconst balance = await walletConnector.getBalance(identity, addresses[0]);\n\tif (balance === 0n) {\n\t\tlet address0 = addresses[0];\n\n\t\tif (\n\t\t\tdefaultWalletConnectorType.startsWith(WalletConnectorType.Iota) &&\n\t\t\tIs.stringValue(envVars.iotaExplorerEndpoint)\n\t\t) {\n\t\t\taddress0 = `${StringHelper.trimTrailingSlashes(envVars.iotaExplorerEndpoint)}/address/${address0}?network=${envVars.iotaNetwork}`;\n\t\t}\n\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.fundingWallet\", { address: address0 }));\n\n\t\t// Add some funds to the wallet from the faucet\n\t\tawait walletConnector.ensureBalance(identity, addresses[0], 1000000000n);\n\t} else {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.fundedWallet\"));\n\t}\n\treturn addresses;\n}\n\n/**\n * Bootstrap the identity for the node.\n * @param engineCore The engine core for the node.\n * @param envVars The environment variables for the node.\n * @param controller The controller for the identity.\n * @param identity The existing identity if there is one.\n * @param identityType The type of identity.\n * @returns The addresses for the wallet.\n */\nasync function generateIdentity(\n\tengineCore: IEngineCore,\n\tenvVars: INodeEnvironmentVariables,\n\tcontroller: string,\n\tidentity: string,\n\tidentityType: \"node\" | \"organization\" | \"user\"\n): Promise<string> {\n\tconst defaultIdentityConnectorType = engineCore.getRegisteredInstanceType(\"identityConnector\");\n\n\t// Now create an identity for the node controlled by the address we just funded\n\tconst identityConnector = IdentityConnectorFactory.get(defaultIdentityConnectorType);\n\n\tlet identityDocument;\n\n\ttry {\n\t\tconst defaultIdentityResolverConnectorType = engineCore.getRegisteredInstanceType(\n\t\t\t\"identityResolverConnector\"\n\t\t);\n\n\t\tconst identityResolverConnector = IdentityResolverConnectorFactory.get(\n\t\t\tdefaultIdentityResolverConnectorType\n\t\t);\n\t\tidentityDocument = await identityResolverConnector.resolveDocument(identity);\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.existingIdentity\", { identity }));\n\t} catch {}\n\n\tif (Is.empty(identityDocument)) {\n\t\tengineCore.logInfo(I18n.formatMessage(\"node.generatingIdentity\", { identityType }));\n\n\t\tidentityDocument = await identityConnector.createDocument(controller);\n\n\t\tengineCore.logInfo(\n\t\t\tI18n.formatMessage(\"node.createdIdentity\", { identity: identityDocument.id })\n\t\t);\n\t}\n\n\tif (defaultIdentityConnectorType.startsWith(IdentityConnectorType.Iota)) {\n\t\tconst didUrn = Urn.fromValidString(identityDocument.id);\n\t\tconst didParts = didUrn.parts();\n\t\tconst objectId = didParts[3];\n\n\t\tif (Is.stringValue(envVars.iotaExplorerEndpoint)) {\n\t\t\tengineCore.logInfo(\n\t\t\t\tI18n.formatMessage(\"node.identityExplorer\", {\n\t\t\t\t\turl: `${StringHelper.trimTrailingSlashes(envVars.iotaExplorerEndpoint)}/object/${objectId}?network=${envVars.iotaNetwork}`\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}\n\treturn identityDocument.id;\n}\n"]}
package/dist/es/node.js CHANGED
@@ -23,7 +23,7 @@ export async function run(nodeOptions) {
23
23
  nodeOptions ??= {};
24
24
  const serverInfo = {
25
25
  name: nodeOptions?.serverName ?? "TWIN Node Server",
26
- version: nodeOptions?.serverVersion ?? "0.0.3-next.0" // x-release-please-version
26
+ version: nodeOptions?.serverVersion ?? "0.0.3-next.4" // x-release-please-version
27
27
  };
28
28
  CLIDisplay.header(serverInfo.name, serverInfo.version, "đŸŒŠī¸ ");
29
29
  if (!Is.stringValue(nodeOptions?.executionDirectory)) {
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { execSync } from \"node:child_process\";\nimport path from \"node:path\";\nimport type { IServerInfo } from \"@twin.org/api-models\";\nimport { CLIDisplay } from \"@twin.org/cli-core\";\nimport { Coerce, EnvHelper, GeneralError, Is } from \"@twin.org/core\";\nimport type { Engine } from \"@twin.org/engine\";\nimport type { EngineServer } from \"@twin.org/engine-server\";\nimport type { IEngineServerConfig } from \"@twin.org/engine-server-types\";\nimport { ModuleHelper } from \"@twin.org/modules\";\nimport * as dotenv from \"dotenv\";\nimport { buildEngineConfiguration } from \"./builders/engineEnvBuilder.js\";\nimport { buildEngineServerConfiguration } from \"./builders/engineServerEnvBuilder.js\";\nimport { extensionsConfiguration } from \"./builders/extensionsBuilder.js\";\nimport type { INodeEngineConfig } from \"./models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"./models/INodeEngineState.js\";\nimport type { INodeEnvironmentVariables } from \"./models/INodeEnvironmentVariables.js\";\nimport type { INodeOptions } from \"./models/INodeOptions.js\";\nimport { ModuleProtocol } from \"./models/moduleProtocol.js\";\nimport { start } from \"./server.js\";\nimport {\n\tcreateModuleImportUrl,\n\tfileExists,\n\tgetExecutionDirectory,\n\tgetExtensionsCacheDir,\n\thandleHttpsProtocol,\n\thandleNpmProtocol,\n\tinitialiseLocales,\n\tloadJsonFile,\n\tloadTextFile,\n\tparseModuleProtocol,\n\tresolvePackageEntryPoint\n} from \"./utils.js\";\n\nconst moduleCache: { [id: string]: unknown } = {};\n\n/**\n * Run the TWIN Node server.\n * @param nodeOptions Optional configuration options for running the server.\n * @returns A promise that resolves when the server is started containing a shutdown method.\n */\nexport async function run(nodeOptions?: INodeOptions): Promise<\n\t| {\n\t\t\tengine: Engine<IEngineServerConfig, INodeEngineState>;\n\t\t\tserver: EngineServer;\n\t\t\tshutdown: () => Promise<void>;\n\t }\n\t| undefined\n> {\n\ttry {\n\t\tnodeOptions ??= {};\n\n\t\tconst serverInfo: IServerInfo = {\n\t\t\tname: nodeOptions?.serverName ?? \"TWIN Node Server\",\n\t\t\tversion: nodeOptions?.serverVersion ?? \"0.0.3-next.0\" // x-release-please-version\n\t\t};\n\n\t\tCLIDisplay.header(serverInfo.name, serverInfo.version, \"đŸŒŠī¸ \");\n\n\t\tif (!Is.stringValue(nodeOptions?.executionDirectory)) {\n\t\t\tnodeOptions.executionDirectory = getExecutionDirectory();\n\t\t}\n\t\tCLIDisplay.value(\"Execution Directory\", nodeOptions.executionDirectory);\n\n\t\tnodeOptions.localesDirectory =\n\t\t\tnodeOptions?.localesDirectory ??\n\t\t\tpath.resolve(path.join(nodeOptions.executionDirectory, \"dist\", \"locales\"));\n\t\tCLIDisplay.value(\"Locales Directory\", nodeOptions.localesDirectory);\n\n\t\tawait initialiseLocales(nodeOptions.localesDirectory);\n\n\t\tif (Is.empty(nodeOptions?.openApiSpecFile)) {\n\t\t\tconst specFile = path.resolve(\n\t\t\t\tpath.join(nodeOptions.executionDirectory ?? \"\", \"docs\", \"open-api\", \"spec.json\")\n\t\t\t);\n\t\t\tCLIDisplay.value(\"Default OpenAPI Spec File\", specFile);\n\t\t\tif (await fileExists(specFile)) {\n\t\t\t\tnodeOptions ??= {};\n\t\t\t\tnodeOptions.openApiSpecFile = specFile;\n\t\t\t}\n\t\t} else {\n\t\t\tCLIDisplay.value(\"OpenAPI Spec File\", nodeOptions.openApiSpecFile);\n\t\t}\n\n\t\tif (Is.empty(nodeOptions?.favIconFile)) {\n\t\t\tconst favIconFile = path.resolve(\n\t\t\t\tpath.join(nodeOptions.executionDirectory ?? \"\", \"static\", \"favicon.png\")\n\t\t\t);\n\t\t\tCLIDisplay.value(\"Default Favicon File\", favIconFile);\n\t\t\tif (await fileExists(favIconFile)) {\n\t\t\t\tnodeOptions ??= {};\n\t\t\t\tnodeOptions.favIconFile = favIconFile;\n\t\t\t}\n\t\t} else {\n\t\t\tCLIDisplay.value(\"Favicon File\", nodeOptions.favIconFile);\n\t\t}\n\n\t\tnodeOptions.envPrefix ??= \"TWIN_\";\n\t\tCLIDisplay.value(\"Environment Variable Prefix\", nodeOptions.envPrefix);\n\n\t\toverrideModuleImport(nodeOptions.executionDirectory ?? \"\");\n\n\t\t// This is the only location in the code base that should access process.env directly\n\t\t// So we can safely disable the linting rule here.\n\t\tlet finalEnvVars =\n\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\tprocess.env as {\n\t\t\t\t[id: string]: string;\n\t\t\t};\n\n\t\tif (Is.objectValue(nodeOptions?.envVars)) {\n\t\t\tfinalEnvVars = {\n\t\t\t\t...finalEnvVars,\n\t\t\t\t...nodeOptions.envVars\n\t\t\t};\n\t\t}\n\n\t\tconst {\n\t\t\tnodeEngineConfig,\n\t\t\tnodeEnvVars: envVars,\n\t\t\tavailableContextIdKeys\n\t\t} = await buildConfiguration(finalEnvVars, nodeOptions, serverInfo);\n\n\t\tCLIDisplay.break();\n\t\tconst startResult = await start(nodeOptions, nodeEngineConfig, envVars, availableContextIdKeys);\n\n\t\tif (!Is.empty(startResult)) {\n\t\t\tfor (const signal of [\"SIGHUP\", \"SIGINT\", \"SIGTERM\"]) {\n\t\t\t\tprocess.on(signal, async () => {\n\t\t\t\t\tCLIDisplay.value(\"Terminate Signal\", signal);\n\t\t\t\t\tawait startResult.shutdown();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn startResult;\n\t} catch (err) {\n\t\tif (nodeOptions?.disableProcessExitOnFailure ?? false) {\n\t\t\tthrow err;\n\t\t}\n\t\tCLIDisplay.error(err);\n\t\t// eslint-disable-next-line unicorn/no-process-exit\n\t\tprocess.exit(1);\n\t}\n}\n\n/**\n * Build the configuration for the TWIN Node server.\n * @param processEnv The environment variables from the process.\n * @param options The options for running the server.\n * @param serverInfo The server information.\n * @returns A promise that resolves to the engine server configuration, environment prefix, environment variables,\n * and options.\n */\nexport async function buildConfiguration(\n\tprocessEnv: {\n\t\t[id: string]: string;\n\t},\n\toptions: INodeOptions,\n\tserverInfo: IServerInfo\n): Promise<{\n\tnodeEnvVars: INodeEnvironmentVariables & { [id: string]: string | unknown };\n\tnodeEngineConfig: INodeEngineConfig;\n\tavailableContextIdKeys: { key: string; componentFeatures: string[] }[];\n}> {\n\tconst availableContextIdKeys: { key: string; componentFeatures: string[] }[] = [];\n\n\tlet defaultEnvOnly = false;\n\tif (Is.empty(options?.envFilenames)) {\n\t\tconst envFile = path.resolve(path.join(options.executionDirectory ?? \"\", \".env\"));\n\t\tCLIDisplay.value(\"Default Environment File\", envFile);\n\t\toptions ??= {};\n\t\toptions.envFilenames = [envFile];\n\t\tdefaultEnvOnly = true;\n\t}\n\n\tif (Is.arrayValue(options?.envFilenames)) {\n\t\tconst output = dotenv.config({\n\t\t\tpath: options?.envFilenames,\n\t\t\tquiet: true\n\t\t});\n\n\t\t// We don't want to throw an error if the default environment file is not found.\n\t\t// Only if we have custom environment files.\n\t\tif (!defaultEnvOnly && output.error) {\n\t\t\tthrow output.error;\n\t\t}\n\n\t\tif (Is.objectValue(output.parsed)) {\n\t\t\tObject.assign(processEnv, output.parsed);\n\t\t}\n\t}\n\n\tconst envVars = EnvHelper.envToJson<{ [id: string]: string | unknown }>(\n\t\tprocessEnv,\n\t\toptions.envPrefix ?? \"\"\n\t);\n\n\t// Expand any environment variables that use the @file: syntax\n\tconst keys = Object.keys(envVars);\n\tfor (const key of keys) {\n\t\tif (\n\t\t\tIs.stringValue(envVars[key]) &&\n\t\t\t(envVars[key].startsWith(\"@text:\") || envVars[key].startsWith(\"@json:\"))\n\t\t) {\n\t\t\tconst filePath = envVars[key].slice(6).trim();\n\t\t\tconst embeddedFile = path.resolve(path.join(options.executionDirectory ?? \"\", filePath));\n\n\t\t\tif (envVars[key].startsWith(\"@text:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from text file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadTextFile(embeddedFile);\n\t\t\t} else if (envVars[key].startsWith(\"@json:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from JSON file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadJsonFile(embeddedFile);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Extend the environment variables with any additional custom configuration.\n\tif (Is.function(options?.extendEnvVars)) {\n\t\tCLIDisplay.task(\"Extending Environment Variables\");\n\t\tawait options.extendEnvVars(envVars);\n\t}\n\n\t// Build the engine configuration from the environment variables.\n\tconst coreConfig = await buildEngineConfiguration(envVars, availableContextIdKeys);\n\tconst engineServerConfig = await buildEngineServerConfiguration(\n\t\tenvVars,\n\t\tavailableContextIdKeys,\n\t\tcoreConfig,\n\t\tserverInfo,\n\t\toptions?.openApiSpecFile,\n\t\toptions?.favIconFile\n\t);\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.arrayValue(options?.configFilenames)) {\n\t\tfor (const configFile of options.configFilenames) {\n\t\t\tCLIDisplay.value(\"Loading Configuration File\", configFile);\n\t\t\tconst configFilePath = path.resolve(path.join(options.executionDirectory ?? \"\", configFile));\n\t\t\tconst config = await loadJsonFile(configFilePath);\n\t\t\tObject.assign(engineServerConfig, config);\n\t\t}\n\t}\n\n\tif (Is.objectValue(options?.config)) {\n\t\tCLIDisplay.task(\"Merging Custom Configuration\");\n\t\tObject.assign(engineServerConfig, options.config);\n\t}\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.function(options?.extendConfig)) {\n\t\tCLIDisplay.task(\"Extending Configuration\");\n\t\tawait options.extendConfig(envVars, engineServerConfig);\n\t}\n\n\tconst nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);\n\n\treturn { nodeEngineConfig, nodeEnvVars: envVars, availableContextIdKeys };\n}\n\n/**\n * Override module imports to support protocol-based loading (npm:, https:) and local files.\n * @param executionDirectory The execution directory for resolving local module paths.\n * @param envVars The environment variables containing extension configuration (optional, uses defaults if not provided).\n */\nexport function overrideModuleImport(\n\texecutionDirectory: string,\n\tenvVars?: INodeEnvironmentVariables\n): void {\n\tconst maxSizeMb = Coerce.number(envVars?.extensionsMaxSizeMb) ?? 10;\n\tconst cacheDirectory = envVars?.extensionsCacheDirectory;\n\n\tModuleHelper.overrideImport(async moduleName => {\n\t\tif (moduleCache[moduleName]) {\n\t\t\treturn {\n\t\t\t\tmodule: moduleCache[moduleName],\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\tconst parsed = parseModuleProtocol(moduleName);\n\t\tlet resolvedPath: string | undefined;\n\n\t\tswitch (parsed.protocol) {\n\t\t\tcase ModuleProtocol.Npm: {\n\t\t\t\tconst result = await handleNpmProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tcacheDirectory\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Https: {\n\t\t\t\tconst result = await handleHttpsProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tmaxSizeMb,\n\t\t\t\t\tcacheDirectory,\n\t\t\t\t\tenvVars?.extensionsCacheTtlHours,\n\t\t\t\t\tenvVars?.extensionsForceRefresh\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Http: {\n\t\t\t\tthrow new GeneralError(\"node\", \"insecureProtocol\", { protocol: ModuleProtocol.Http });\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Local: {\n\t\t\t\tlet localFilename = path.resolve(moduleName);\n\n\t\t\t\tlet exists = await fileExists(localFilename);\n\t\t\t\tif (!exists) {\n\t\t\t\t\tlocalFilename = path.resolve(executionDirectory, moduleName);\n\t\t\t\t\texists = await fileExists(localFilename);\n\t\t\t\t}\n\n\t\t\t\tif (exists) {\n\t\t\t\t\tresolvedPath = localFilename;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Default: {\n\t\t\t\ttry {\n\t\t\t\t\tconst npmRoot = execSync(\"npm root\").toString().trim().replace(/\\\\/g, \"/\");\n\t\t\t\t\tconst packagePath = path.resolve(npmRoot, moduleName);\n\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Continue to fallback resolution\n\t\t\t\t}\n\n\t\t\t\t// Fallback: resolve from npm protocol cache directory (installed via handleNpmProtocol)\n\t\t\t\ttry {\n\t\t\t\t\tconst cacheNpmRoot = path.resolve(\n\t\t\t\t\t\tgetExtensionsCacheDir(executionDirectory, ModuleProtocol.Npm, cacheDirectory),\n\t\t\t\t\t\t\"node_modules\"\n\t\t\t\t\t);\n\n\t\t\t\t\tconst packagePath = path.resolve(cacheNpmRoot, moduleName);\n\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// No cached resolution either; fall through\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Common module loading and caching logic\n\t\tif (resolvedPath) {\n\t\t\tconst module = await import(createModuleImportUrl(resolvedPath));\n\t\t\tmoduleCache[moduleName] = module;\n\t\t\treturn {\n\t\t\t\tmodule,\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: undefined,\n\t\t\tuseDefault: true\n\t\t};\n\t});\n}\n"]}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { execSync } from \"node:child_process\";\nimport path from \"node:path\";\nimport type { IServerInfo } from \"@twin.org/api-models\";\nimport { CLIDisplay } from \"@twin.org/cli-core\";\nimport { Coerce, EnvHelper, GeneralError, Is } from \"@twin.org/core\";\nimport type { Engine } from \"@twin.org/engine\";\nimport type { EngineServer } from \"@twin.org/engine-server\";\nimport type { IEngineServerConfig } from \"@twin.org/engine-server-types\";\nimport { ModuleHelper } from \"@twin.org/modules\";\nimport * as dotenv from \"dotenv\";\nimport { buildEngineConfiguration } from \"./builders/engineEnvBuilder.js\";\nimport { buildEngineServerConfiguration } from \"./builders/engineServerEnvBuilder.js\";\nimport { extensionsConfiguration } from \"./builders/extensionsBuilder.js\";\nimport type { INodeEngineConfig } from \"./models/INodeEngineConfig.js\";\nimport type { INodeEngineState } from \"./models/INodeEngineState.js\";\nimport type { INodeEnvironmentVariables } from \"./models/INodeEnvironmentVariables.js\";\nimport type { INodeOptions } from \"./models/INodeOptions.js\";\nimport { ModuleProtocol } from \"./models/moduleProtocol.js\";\nimport { start } from \"./server.js\";\nimport {\n\tcreateModuleImportUrl,\n\tfileExists,\n\tgetExecutionDirectory,\n\tgetExtensionsCacheDir,\n\thandleHttpsProtocol,\n\thandleNpmProtocol,\n\tinitialiseLocales,\n\tloadJsonFile,\n\tloadTextFile,\n\tparseModuleProtocol,\n\tresolvePackageEntryPoint\n} from \"./utils.js\";\n\nconst moduleCache: { [id: string]: unknown } = {};\n\n/**\n * Run the TWIN Node server.\n * @param nodeOptions Optional configuration options for running the server.\n * @returns A promise that resolves when the server is started containing a shutdown method.\n */\nexport async function run(nodeOptions?: INodeOptions): Promise<\n\t| {\n\t\t\tengine: Engine<IEngineServerConfig, INodeEngineState>;\n\t\t\tserver: EngineServer;\n\t\t\tshutdown: () => Promise<void>;\n\t }\n\t| undefined\n> {\n\ttry {\n\t\tnodeOptions ??= {};\n\n\t\tconst serverInfo: IServerInfo = {\n\t\t\tname: nodeOptions?.serverName ?? \"TWIN Node Server\",\n\t\t\tversion: nodeOptions?.serverVersion ?? \"0.0.3-next.4\" // x-release-please-version\n\t\t};\n\n\t\tCLIDisplay.header(serverInfo.name, serverInfo.version, \"đŸŒŠī¸ \");\n\n\t\tif (!Is.stringValue(nodeOptions?.executionDirectory)) {\n\t\t\tnodeOptions.executionDirectory = getExecutionDirectory();\n\t\t}\n\t\tCLIDisplay.value(\"Execution Directory\", nodeOptions.executionDirectory);\n\n\t\tnodeOptions.localesDirectory =\n\t\t\tnodeOptions?.localesDirectory ??\n\t\t\tpath.resolve(path.join(nodeOptions.executionDirectory, \"dist\", \"locales\"));\n\t\tCLIDisplay.value(\"Locales Directory\", nodeOptions.localesDirectory);\n\n\t\tawait initialiseLocales(nodeOptions.localesDirectory);\n\n\t\tif (Is.empty(nodeOptions?.openApiSpecFile)) {\n\t\t\tconst specFile = path.resolve(\n\t\t\t\tpath.join(nodeOptions.executionDirectory ?? \"\", \"docs\", \"open-api\", \"spec.json\")\n\t\t\t);\n\t\t\tCLIDisplay.value(\"Default OpenAPI Spec File\", specFile);\n\t\t\tif (await fileExists(specFile)) {\n\t\t\t\tnodeOptions ??= {};\n\t\t\t\tnodeOptions.openApiSpecFile = specFile;\n\t\t\t}\n\t\t} else {\n\t\t\tCLIDisplay.value(\"OpenAPI Spec File\", nodeOptions.openApiSpecFile);\n\t\t}\n\n\t\tif (Is.empty(nodeOptions?.favIconFile)) {\n\t\t\tconst favIconFile = path.resolve(\n\t\t\t\tpath.join(nodeOptions.executionDirectory ?? \"\", \"static\", \"favicon.png\")\n\t\t\t);\n\t\t\tCLIDisplay.value(\"Default Favicon File\", favIconFile);\n\t\t\tif (await fileExists(favIconFile)) {\n\t\t\t\tnodeOptions ??= {};\n\t\t\t\tnodeOptions.favIconFile = favIconFile;\n\t\t\t}\n\t\t} else {\n\t\t\tCLIDisplay.value(\"Favicon File\", nodeOptions.favIconFile);\n\t\t}\n\n\t\tnodeOptions.envPrefix ??= \"TWIN_\";\n\t\tCLIDisplay.value(\"Environment Variable Prefix\", nodeOptions.envPrefix);\n\n\t\toverrideModuleImport(nodeOptions.executionDirectory ?? \"\");\n\n\t\t// This is the only location in the code base that should access process.env directly\n\t\t// So we can safely disable the linting rule here.\n\t\tlet finalEnvVars =\n\t\t\t// eslint-disable-next-line no-restricted-syntax\n\t\t\tprocess.env as {\n\t\t\t\t[id: string]: string;\n\t\t\t};\n\n\t\tif (Is.objectValue(nodeOptions?.envVars)) {\n\t\t\tfinalEnvVars = {\n\t\t\t\t...finalEnvVars,\n\t\t\t\t...nodeOptions.envVars\n\t\t\t};\n\t\t}\n\n\t\tconst {\n\t\t\tnodeEngineConfig,\n\t\t\tnodeEnvVars: envVars,\n\t\t\tavailableContextIdKeys\n\t\t} = await buildConfiguration(finalEnvVars, nodeOptions, serverInfo);\n\n\t\tCLIDisplay.break();\n\t\tconst startResult = await start(nodeOptions, nodeEngineConfig, envVars, availableContextIdKeys);\n\n\t\tif (!Is.empty(startResult)) {\n\t\t\tfor (const signal of [\"SIGHUP\", \"SIGINT\", \"SIGTERM\"]) {\n\t\t\t\tprocess.on(signal, async () => {\n\t\t\t\t\tCLIDisplay.value(\"Terminate Signal\", signal);\n\t\t\t\t\tawait startResult.shutdown();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn startResult;\n\t} catch (err) {\n\t\tif (nodeOptions?.disableProcessExitOnFailure ?? false) {\n\t\t\tthrow err;\n\t\t}\n\t\tCLIDisplay.error(err);\n\t\t// eslint-disable-next-line unicorn/no-process-exit\n\t\tprocess.exit(1);\n\t}\n}\n\n/**\n * Build the configuration for the TWIN Node server.\n * @param processEnv The environment variables from the process.\n * @param options The options for running the server.\n * @param serverInfo The server information.\n * @returns A promise that resolves to the engine server configuration, environment prefix, environment variables,\n * and options.\n */\nexport async function buildConfiguration(\n\tprocessEnv: {\n\t\t[id: string]: string;\n\t},\n\toptions: INodeOptions,\n\tserverInfo: IServerInfo\n): Promise<{\n\tnodeEnvVars: INodeEnvironmentVariables & { [id: string]: string | unknown };\n\tnodeEngineConfig: INodeEngineConfig;\n\tavailableContextIdKeys: { key: string; componentFeatures: string[] }[];\n}> {\n\tconst availableContextIdKeys: { key: string; componentFeatures: string[] }[] = [];\n\n\tlet defaultEnvOnly = false;\n\tif (Is.empty(options?.envFilenames)) {\n\t\tconst envFile = path.resolve(path.join(options.executionDirectory ?? \"\", \".env\"));\n\t\tCLIDisplay.value(\"Default Environment File\", envFile);\n\t\toptions ??= {};\n\t\toptions.envFilenames = [envFile];\n\t\tdefaultEnvOnly = true;\n\t}\n\n\tif (Is.arrayValue(options?.envFilenames)) {\n\t\tconst output = dotenv.config({\n\t\t\tpath: options?.envFilenames,\n\t\t\tquiet: true\n\t\t});\n\n\t\t// We don't want to throw an error if the default environment file is not found.\n\t\t// Only if we have custom environment files.\n\t\tif (!defaultEnvOnly && output.error) {\n\t\t\tthrow output.error;\n\t\t}\n\n\t\tif (Is.objectValue(output.parsed)) {\n\t\t\tObject.assign(processEnv, output.parsed);\n\t\t}\n\t}\n\n\tconst envVars = EnvHelper.envToJson<{ [id: string]: string | unknown }>(\n\t\tprocessEnv,\n\t\toptions.envPrefix ?? \"\"\n\t);\n\n\t// Expand any environment variables that use the @file: syntax\n\tconst keys = Object.keys(envVars);\n\tfor (const key of keys) {\n\t\tif (\n\t\t\tIs.stringValue(envVars[key]) &&\n\t\t\t(envVars[key].startsWith(\"@text:\") || envVars[key].startsWith(\"@json:\"))\n\t\t) {\n\t\t\tconst filePath = envVars[key].slice(6).trim();\n\t\t\tconst embeddedFile = path.resolve(path.join(options.executionDirectory ?? \"\", filePath));\n\n\t\t\tif (envVars[key].startsWith(\"@text:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from text file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadTextFile(embeddedFile);\n\t\t\t} else if (envVars[key].startsWith(\"@json:\")) {\n\t\t\t\tCLIDisplay.value(`Expanding Environment Variable: ${key} from JSON file`, embeddedFile);\n\t\t\t\tenvVars[key] = await loadJsonFile(embeddedFile);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Extend the environment variables with any additional custom configuration.\n\tif (Is.function(options?.extendEnvVars)) {\n\t\tCLIDisplay.task(\"Extending Environment Variables\");\n\t\tawait options.extendEnvVars(envVars);\n\t}\n\n\t// Build the engine configuration from the environment variables.\n\tconst coreConfig = await buildEngineConfiguration(envVars, availableContextIdKeys);\n\tconst engineServerConfig = await buildEngineServerConfiguration(\n\t\tenvVars,\n\t\tavailableContextIdKeys,\n\t\tcoreConfig,\n\t\tserverInfo,\n\t\toptions?.openApiSpecFile,\n\t\toptions?.favIconFile\n\t);\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.arrayValue(options?.configFilenames)) {\n\t\tfor (const configFile of options.configFilenames) {\n\t\t\tCLIDisplay.value(\"Loading Configuration File\", configFile);\n\t\t\tconst configFilePath = path.resolve(path.join(options.executionDirectory ?? \"\", configFile));\n\t\t\tconst config = await loadJsonFile(configFilePath);\n\t\t\tObject.assign(engineServerConfig, config);\n\t\t}\n\t}\n\n\tif (Is.objectValue(options?.config)) {\n\t\tCLIDisplay.task(\"Merging Custom Configuration\");\n\t\tObject.assign(engineServerConfig, options.config);\n\t}\n\n\t// Merge any custom configuration provided in the options.\n\tif (Is.function(options?.extendConfig)) {\n\t\tCLIDisplay.task(\"Extending Configuration\");\n\t\tawait options.extendConfig(envVars, engineServerConfig);\n\t}\n\n\tconst nodeEngineConfig = await extensionsConfiguration(envVars, engineServerConfig);\n\n\treturn { nodeEngineConfig, nodeEnvVars: envVars, availableContextIdKeys };\n}\n\n/**\n * Override module imports to support protocol-based loading (npm:, https:) and local files.\n * @param executionDirectory The execution directory for resolving local module paths.\n * @param envVars The environment variables containing extension configuration (optional, uses defaults if not provided).\n */\nexport function overrideModuleImport(\n\texecutionDirectory: string,\n\tenvVars?: INodeEnvironmentVariables\n): void {\n\tconst maxSizeMb = Coerce.number(envVars?.extensionsMaxSizeMb) ?? 10;\n\tconst cacheDirectory = envVars?.extensionsCacheDirectory;\n\n\tModuleHelper.overrideImport(async moduleName => {\n\t\tif (moduleCache[moduleName]) {\n\t\t\treturn {\n\t\t\t\tmodule: moduleCache[moduleName],\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\tconst parsed = parseModuleProtocol(moduleName);\n\t\tlet resolvedPath: string | undefined;\n\n\t\tswitch (parsed.protocol) {\n\t\t\tcase ModuleProtocol.Npm: {\n\t\t\t\tconst result = await handleNpmProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tcacheDirectory\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Https: {\n\t\t\t\tconst result = await handleHttpsProtocol(\n\t\t\t\t\tparsed.identifier,\n\t\t\t\t\texecutionDirectory,\n\t\t\t\t\tmaxSizeMb,\n\t\t\t\t\tcacheDirectory,\n\t\t\t\t\tenvVars?.extensionsCacheTtlHours,\n\t\t\t\t\tenvVars?.extensionsForceRefresh\n\t\t\t\t);\n\t\t\t\tresolvedPath = result.resolvedPath;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Http: {\n\t\t\t\tthrow new GeneralError(\"node\", \"insecureProtocol\", { protocol: ModuleProtocol.Http });\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Local: {\n\t\t\t\tlet localFilename = path.resolve(moduleName);\n\n\t\t\t\tlet exists = await fileExists(localFilename);\n\t\t\t\tif (!exists) {\n\t\t\t\t\tlocalFilename = path.resolve(executionDirectory, moduleName);\n\t\t\t\t\texists = await fileExists(localFilename);\n\t\t\t\t}\n\n\t\t\t\tif (exists) {\n\t\t\t\t\tresolvedPath = localFilename;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase ModuleProtocol.Default: {\n\t\t\t\ttry {\n\t\t\t\t\tconst npmRoot = execSync(\"npm root\").toString().trim().replace(/\\\\/g, \"/\");\n\t\t\t\t\tconst packagePath = path.resolve(npmRoot, moduleName);\n\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Continue to fallback resolution\n\t\t\t\t}\n\n\t\t\t\t// Fallback: resolve from npm protocol cache directory (installed via handleNpmProtocol)\n\t\t\t\ttry {\n\t\t\t\t\tconst cacheNpmRoot = path.resolve(\n\t\t\t\t\t\tgetExtensionsCacheDir(executionDirectory, ModuleProtocol.Npm, cacheDirectory),\n\t\t\t\t\t\t\"node_modules\"\n\t\t\t\t\t);\n\n\t\t\t\t\tconst packagePath = path.resolve(cacheNpmRoot, moduleName);\n\t\t\t\t\tconst mainFile = await resolvePackageEntryPoint(packagePath, moduleName);\n\t\t\t\t\tconst modulePath = path.resolve(packagePath, mainFile);\n\t\t\t\t\tconst exists = await fileExists(modulePath);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tresolvedPath = modulePath;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// No cached resolution either; fall through\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Common module loading and caching logic\n\t\tif (resolvedPath) {\n\t\t\tconst module = await import(createModuleImportUrl(resolvedPath));\n\t\t\tmoduleCache[moduleName] = module;\n\t\t\treturn {\n\t\t\t\tmodule,\n\t\t\t\tuseDefault: false\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: undefined,\n\t\t\tuseDefault: true\n\t\t};\n\t});\n}\n"]}
package/docs/changelog.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @twin.org/node-core - Changelog
2
2
 
3
+ ## [0.0.3-next.4](https://github.com/twinfoundation/node/compare/node-core-v0.0.3-next.3...node-core-v0.0.3-next.4) (2025-11-24)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * org identity verification methods ([18f158b](https://github.com/twinfoundation/node/commit/18f158b2f63930e20e94437c17ed43421771a458))
9
+
3
10
  ## [0.0.3-next.3](https://github.com/twinfoundation/node/compare/node-core-v0.0.3-next.2...node-core-v0.0.3-next.3) (2025-11-20)
4
11
 
5
12
 
package/locales/en.json CHANGED
@@ -10,9 +10,9 @@
10
10
  }
11
11
  },
12
12
  "node": {
13
- "generatingMnemonic": "Generating mnemonic \"{mnemonic}\"",
14
13
  "storingMnemonic": "Storing mnemonic",
15
14
  "existingMnemonic": "Mnemonic already exists",
15
+ "finalMnemonic": "Mnemonic is stored in the vault under the key \"{vaultKey}\"",
16
16
  "fundingWallet": "Funding wallet \"{address}\"",
17
17
  "fundedWallet": "Wallet already funded",
18
18
  "processingIdentity": "Processing identity of type \"{identityType}\"",
@@ -36,7 +36,7 @@
36
36
  "existingUserProfile": "User profile already exists \"{identity}\"",
37
37
  "nodeId": "Node identity \"{identity}\"",
38
38
  "nodeAdminUserEmail": "Node Admin User Email \"{email}\"",
39
- "nodeAdminUserPassword": "Node Admin User Password \"{password}\"",
39
+ "nodeAdminUserPassword": "Node Admin User Password Generated and stored in the vault under the key \"{vaultKey}\"",
40
40
  "extensionLoading": "Loading Extension",
41
41
  "extensionInitialisingEngine": "Initialising engine for extension \"{extension}\"",
42
42
  "extensionInitialisingEngineServer": "Initialising engine server for extension \"{extension}\"",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/node-core",
3
- "version": "0.0.3-next.3",
3
+ "version": "0.0.3-next.4",
4
4
  "description": "TWIN Node Core for serving APIs using the specified configuration",
5
5
  "repository": {
6
6
  "type": "git",